NoRoot Firewall v4.0.2版本的 MD5 值为:65ececf86f2a47bb27bef1872f52b654

以下内容为反编译后的 MyVpnService.java 源代码,内容仅作参考


package app.greyshirts.firewall.app;

import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.net.VpnService;
import android.os.Build;
import android.os.Handler;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import android.widget.Toast;
import androidx.core.app.NotificationCompat;
import app.greyshirts.firewall.R;
import app.greyshirts.firewall.app.debuglog.PersistentLog;
import app.greyshirts.firewall.proxy.ProxyWorker;
import app.greyshirts.firewall.ui.ActivityPager;
import app.greyshirts.firewall.ui.MyUncaughtExceptionHandler;
import java.util.ArrayList;
import java.util.Locale;
public class MyVpnService extends VpnService implements Runnable {
    private Handler handler = null;

    public static void notifyBlockingRuleChange(Context context) {
        ProxyWorker.getInstance().notifyBlockingRuleChanged();
    }

    public static void notifyNetworkStateChange(Context context) {
        ProxyWorker.getInstance().notifyNetworkStateChanged();
    }

    public static void startService(Context context) {
        Intent intent = new Intent(context, MyVpnService.class);
        intent.putExtra("cmd", 1);
        if (Build.VERSION.SDK_INT >= 26) {
            context.startForegroundService(intent);
        } else {
            context.startService(intent);
        }
    }

    public static void stopService(Context context) {
        Intent intent = new Intent(context, MyVpnService.class);
        intent.putExtra("cmd", 2);
        if (Build.VERSION.SDK_INT >= 26) {
            context.startForegroundService(intent);
        } else {
            context.startService(intent);
        }
    }

    @Override
    public int onStartCommand(Intent intent, int i, int i2) {
        PersistentLog persistentLog = PersistentLog.getInstance(this);
        StringBuilder sb = new StringBuilder();
        sb.append("VpnService: onStartCommand intent=");
        sb.append(intent != null ? intent.toString() : "(null)");
        sb.append(" flags=");
        sb.append(i);
        persistentLog.i(sb.toString(), new Object[0]);
        StringBuilder sb2 = new StringBuilder();
        sb2.append("VpnService onStartCommand intent=");
        sb2.append(intent != null ? intent.toString() : "(null)");
        sb2.append(" flags=");
        sb2.append(i);
        Log.i("NRFW", sb2.toString());
        if (!MyUncaughtExceptionHandler.isSet()) {
            Thread.setDefaultUncaughtExceptionHandler(new MyUncaughtExceptionHandler(getApplicationContext()));
        }
        if (intent == null) {
            Toast.makeText(this, "Service restarted", 0).show();
            Log.i("NRFW", "service restarted");
            PersistentLog.getInstance(this).i("VpnService: intent=null. that means server is restarted automatically. Send STARTVPN command myself", new Object[0]);
            intent = new Intent();
            intent.putExtra("cmd", 1);
        }
        int intExtra = intent.getIntExtra("cmd", 1);
        if (intExtra == 1) {
            if (Build.VERSION.SDK_INT >= 26) {
                PendingIntent activity = PendingIntent.getActivity(this, 0, ActivityPager.getStartIntentFromForegroundServiceNotification(this), 134217728);
                NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "foreground_channel_id");
                builder.setSmallIcon(R.drawable.notification_wall);
                builder.setContentTitle(getString(R.string.notification_service_running));
                builder.setContentText(getString(R.string.notification_service_running_body));
                builder.setTicker(getString(R.string.app_name));
                builder.setColor(Color.parseColor("#f78e4b"));
                builder.setAutoCancel(true);
                builder.setContentIntent(activity);
                startForeground(1, builder.getNotification());
            }
            PersistentLog.getInstance(this).i("VpnService: CMD_STARTVPN", new Object[0]);
            this.handler = new Handler();
            new VpnStartThread(this, this).start();
        } else if (intExtra == 2) {
            PersistentLog.getInstance(this).i("VpnService: CMD_STOPVPN", new Object[0]);
            stopVpn();
            PersistentLog.getInstance(this).i("VpnService: call stopSelf()", new Object[0]);
            stopSelf();
        } else if (intExtra == 4) {
            PersistentLog.getInstance(this).i("VpnService: CMD_NOTIFICATION_CLEARED", new Object[0]);
            Filter.getInstance(this).deleteAllPendingList();
            if (!ProxyWorker.getInstance().notifyBlockingRuleChanged()) {
                PersistentLog.getInstance(this).i("VpnService: worker seems not to be running. call stopSelf().", new Object[0]);
                stopSelf();
            }
        } else {
            throw new RuntimeException("Unknown command in MyVpnService: " + intExtra);
        }
        return 1;
    }

    @Override
    public void run() {
        setupVpn();
        Log.i("NRFW", "thread end");
    }

    private void setupVpn() {
        PersistentLog.getInstance(this).i("VpnService: try to setup VPN.", new Object[0]);
        ArrayList<Locale> localeList = getLocaleList();
        Log.i("NRFW", "locale=" + Locale.getDefault().toString());
        int i = 0;
        while (true) {
            VpnService.Builder builder = new VpnService.Builder(this);
            builder.setSession("firewall");
            builder.addAddress("10.0.8.1", 32);
            builder.addRoute("0.0.0.0", 0);
            builder.setMtu(30000);
            try {
                ParcelFileDescriptor establish = builder.establish();
                if (establish == null) {
                    PersistentLog.getInstance(this).i("VpnService: builder.establish() failed. pfd==null", new Object[0]);
                    Handler handler = this.handler;
                    if (handler != null) {
                        handler.post(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(MyVpnService.this, "Cannot establish VPN (app not prepared)", 1).show();
                            }
                        });
                        return;
                    }
                    return;
                }
                PersistentLog.getInstance(this).i("VpnService: call ProxyWorker.start()", new Object[0]);
                ProxyWorker.getInstance().start(this, establish);
                return;
            } catch (IllegalArgumentException e) {
                if (i == localeList.size()) {
                    Locale locale = Locale.getDefault();
                    throw new IllegalArgumentException(e.toString() + " nlocale=" + localeList.size() + " locale=" + locale.toString());
                }
                Locale.setDefault(localeList.get(i));
                Log.i("NRFW", "try locale " + localeList.get(i).toString());
                i++;
            } catch (IllegalStateException e2) {
                PersistentLog persistentLog = PersistentLog.getInstance(this);
                persistentLog.i("VpnService: builder.establish() failed. e=" + e2.toString(), new Object[0]);
                Handler handler2 = this.handler;
                if (handler2 != null) {
                    handler2.post(new Runnable() {
                        @Override
                        public void run() {
                            MyVpnService myVpnService = MyVpnService.this;
                            Toast.makeText(myVpnService, "Cannot establish VPN (" + e2.toString() + ")", 1).show();
                        }
                    });
                    return;
                }
                return;
            }
        }
    }

    private void stopVpn() {
        PersistentLog.getInstance(this).i("VpnService: call ProxyWorker.stop()", new Object[0]);
        ProxyWorker.getInstance().stop();
    }

    private ArrayList<Locale> getLocaleList() {
        ArrayList<Locale> arrayList = new ArrayList<>();
        arrayList.add(Locale.ENGLISH);
        Locale[] availableLocales = Locale.getAvailableLocales();
        if (availableLocales != null) {
            for (Locale locale : availableLocales) {
                arrayList.add(locale);
            }
        }
        return arrayList;
    }

    @Override
    public void onRevoke() {
        Log.i("NRFW", "VpnService: onRevoke() called. ");
        PersistentLog.getInstance(this).i("VpnService: onRevoke() called", new Object[0]);
        stopVpn();
        PersistentLog.getInstance(this).i("VpnService: call stopSelf()", new Object[0]);
        stopSelf();
    }

    @Override
    public void onTrimMemory(int i) {
        super.onTrimMemory(i);
        PersistentLog.getInstance(this).i("VpnService: onTrimMemory() called. level=%d", Integer.valueOf(i));
    }

    @Override
    public void onDestroy() {
        Log.i("NRFW", "VpnService onDestroy() called");
        PersistentLog.getInstance(this).i("VpnService: onDestroy() called", new Object[0]);
    }

    class VpnStartThread extends Thread {
        public VpnStartThread(MyVpnService myVpnService, Runnable runnable) {
            super(runnable, "vpnservice");
            myVpnService.handler = new Handler();
        }
    }
}