diff options
| author | Arne Schwabe <arne@rfc2549.org> | 2016-11-10 12:50:17 +0100 | 
|---|---|---|
| committer | Arne Schwabe <arne@rfc2549.org> | 2016-11-10 12:50:17 +0100 | 
| commit | 5f070fb527e5541a6ad6185ee8cfd51101056eaf (patch) | |
| tree | 3642d9afd85a37331fdf8c1119d3ad0a0e248d1d | |
| parent | b92a1252b395bc875a311eb4e7b4558b7e625483 (diff) | |
First step to process seperation, not everything working yet.
25 files changed, 382 insertions, 72 deletions
| diff --git a/build.gradle b/build.gradle index 1464dd50..7105a6a8 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ buildscript {          jcenter()      }      dependencies { -        classpath 'com.android.tools.build:gradle:2.2.0' +        classpath 'com.android.tools.build:gradle:2.2.2'      }  } diff --git a/main/build.gradle b/main/build.gradle index b42a1077..99e19bb0 100644 --- a/main/build.gradle +++ b/main/build.gradle @@ -26,7 +26,7 @@ android {      defaultConfig {          minSdkVersion 14 -        targetSdkVersion 24 +        targetSdkVersion 25          versionCode = 141          versionName = "0.6.60"      } diff --git a/main/jni/Application.mk b/main/jni/Application.mk index caabab79..dd021c20 100644 --- a/main/jni/Application.mk +++ b/main/jni/Application.mk @@ -9,6 +9,6 @@ APP_STL:=stlport_static  #LOCAL_ARM_MODE := arm -#NDK_TOOLCHAIN_VERSION=clang +NDK_TOOLCHAIN_VERSION=4.9  APP_CPPFLAGS += -std=c++1y  APP_CFLAGS += -funwind-tables diff --git a/main/src/main/AndroidManifest.xml b/main/src/main/AndroidManifest.xml index da2c6ab2..d80ae581 100644 --- a/main/src/main/AndroidManifest.xml +++ b/main/src/main/AndroidManifest.xml @@ -67,14 +67,17 @@          <service              android:name=".core.OpenVPNService" +            android:process=":openvpn"              android:permission="android.permission.BIND_VPN_SERVICE" >              <intent-filter>                  <action android:name="android.net.VpnService" />              </intent-filter> +          </service>          <service              android:name=".api.ExternalOpenVPNService" +            android:process=":openvpn"              tools:ignore="ExportedService">              <intent-filter> @@ -82,6 +85,11 @@              </intent-filter>          </service> +        <service android:name=".core.OpenVPNStatusService" +            android:process=":openvpn" +            android:exported="false" /> + +          <service              android:name=".OpenVPNTileService"              android:value="true" diff --git a/main/src/main/aidl/de/blinkt/openvpn/api/IOpenVPNAPIService.aidl b/main/src/main/aidl/de/blinkt/openvpn/api/IOpenVPNAPIService.aidl index 273a0046..c0108a90 100644 --- a/main/src/main/aidl/de/blinkt/openvpn/api/IOpenVPNAPIService.aidl +++ b/main/src/main/aidl/de/blinkt/openvpn/api/IOpenVPNAPIService.aidl @@ -20,12 +20,12 @@ interface IOpenVPNAPIService {  	/** start a profile using a config as inline string. Make sure that all needed data is inlined,
  	 * e.g., using <ca>...</ca> or <auth-user-data>...</auth-user-data>
  	 * See the OpenVPN manual page for more on inlining files */
 -	void startVPN (String inlineconfig);
 +	void startVPN (in String inlineconfig);
  	/** This permission framework is used  to avoid confused deputy style attack to the VPN
  	 * calling this will give null if the app is allowed to use the external API and an Intent
  	 * that can be launched to request permissions otherwise */
 -	Intent prepare (String packagename);
 +	Intent prepare (in String packagename);
  	/** Used to trigger to the Android VPN permission dialog (VPNService.prepare()) in advance,
  	 * if this return null OpenVPN for ANdroid already has the permissions otherwise you can start the returned Intent
 @@ -44,15 +44,15 @@ interface IOpenVPNAPIService {      /**
        * Registers to receive OpenVPN Status Updates
        */
 -    void registerStatusCallback(IOpenVPNStatusCallback cb);
 +    void registerStatusCallback(in IOpenVPNStatusCallback cb);
      /**
       * Remove a previously registered callback interface.
       */
 -    void unregisterStatusCallback(IOpenVPNStatusCallback cb);
 +    void unregisterStatusCallback(in IOpenVPNStatusCallback cb);
  	/** Remove a profile by UUID */
 -	void removeProfile (String profileUUID);
 +	void removeProfile (in String profileUUID);
  	/** Request a socket to be protected as a VPN socket would be. Useful for creating
  	  * a helper socket for an app controlling OpenVPN
 diff --git a/main/src/main/aidl/de/blinkt/openvpn/api/IOpenVPNStatusCallback.aidl b/main/src/main/aidl/de/blinkt/openvpn/api/IOpenVPNStatusCallback.aidl index 1dfa1381..c7310c6a 100644 --- a/main/src/main/aidl/de/blinkt/openvpn/api/IOpenVPNStatusCallback.aidl +++ b/main/src/main/aidl/de/blinkt/openvpn/api/IOpenVPNStatusCallback.aidl @@ -5,9 +5,9 @@ package de.blinkt.openvpn.api;   * synchronous notifications back to its clients.  Note that this is a
   * one-way interface so the server does not block waiting for the client.
   */
 -oneway interface IOpenVPNStatusCallback {
 +interface IOpenVPNStatusCallback {
      /**
       * Called when the service has a new status for you.
       */
 -    void newStatus(String uuid, String state, String message, String level);
 +    oneway void newStatus(in String uuid, in String state, in String message, in String level);
  }
 diff --git a/main/src/main/aidl/de/blinkt/openvpn/core/ConnectionStatus.aidl b/main/src/main/aidl/de/blinkt/openvpn/core/ConnectionStatus.aidl new file mode 100644 index 00000000..f37c3101 --- /dev/null +++ b/main/src/main/aidl/de/blinkt/openvpn/core/ConnectionStatus.aidl @@ -0,0 +1,3 @@ +package de.blinkt.openvpn.core; + +parcelable ConnectionStatus;
\ No newline at end of file diff --git a/main/src/main/aidl/de/blinkt/openvpn/core/IServiceStatus.aidl b/main/src/main/aidl/de/blinkt/openvpn/core/IServiceStatus.aidl new file mode 100644 index 00000000..49bf0619 --- /dev/null +++ b/main/src/main/aidl/de/blinkt/openvpn/core/IServiceStatus.aidl @@ -0,0 +1,18 @@ +// StatusIPC.aidl +package de.blinkt.openvpn.core; + +// Declare any non-default types here with import statements +import de.blinkt.openvpn.core.IStatusCallbacks; + + +interface IServiceStatus { +         /** +          * Registers to receive OpenVPN Status Updates +          */ +         void registerStatusCallback(in IStatusCallbacks cb); + +         /** +           * Remove a previously registered callback interface. +                 */ +        void unregisterStatusCallback(in IStatusCallbacks cb); +} diff --git a/main/src/main/aidl/de/blinkt/openvpn/core/IStatusCallbacks.aidl b/main/src/main/aidl/de/blinkt/openvpn/core/IStatusCallbacks.aidl new file mode 100644 index 00000000..23bee8b4 --- /dev/null +++ b/main/src/main/aidl/de/blinkt/openvpn/core/IStatusCallbacks.aidl @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2012-2016 Arne Schwabe + * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt + */ + +package de.blinkt.openvpn.core; + +import de.blinkt.openvpn.core.LogItem; +import de.blinkt.openvpn.core.ConnectionStatus; + + +interface IStatusCallbacks { +    /** +     * Called when the service has a new status for you. +     */ +    oneway void newLogItem(in LogItem item); + +    oneway void updateStateString(in String state, in String msg, in int resid, in ConnectionStatus level); + +    oneway void updateByteCount(long inBytes, long outBytes); +} diff --git a/main/src/main/aidl/de/blinkt/openvpn/core/LogItem.aidl b/main/src/main/aidl/de/blinkt/openvpn/core/LogItem.aidl new file mode 100644 index 00000000..9a7291af --- /dev/null +++ b/main/src/main/aidl/de/blinkt/openvpn/core/LogItem.aidl @@ -0,0 +1,3 @@ +package de.blinkt.openvpn.core; + +parcelable LogItem;
\ No newline at end of file diff --git a/main/src/main/java/de/blinkt/openvpn/LaunchVPN.java b/main/src/main/java/de/blinkt/openvpn/LaunchVPN.java index 38549a6c..9490c269 100644 --- a/main/src/main/java/de/blinkt/openvpn/LaunchVPN.java +++ b/main/src/main/java/de/blinkt/openvpn/LaunchVPN.java @@ -28,10 +28,10 @@ import android.widget.EditText;  import java.io.IOException;  import de.blinkt.openvpn.activities.LogWindow; +import de.blinkt.openvpn.core.ConnectionStatus;  import de.blinkt.openvpn.core.ProfileManager;  import de.blinkt.openvpn.core.VPNLaunchHelper;  import de.blinkt.openvpn.core.VpnStatus; -import de.blinkt.openvpn.core.VpnStatus.ConnectionStatus;  /**   * This Activity actually handles two stages of a launcher shortcut's life cycle. diff --git a/main/src/main/java/de/blinkt/openvpn/OpenVPNTileService.java b/main/src/main/java/de/blinkt/openvpn/OpenVPNTileService.java index 7d954894..3996f25e 100644 --- a/main/src/main/java/de/blinkt/openvpn/OpenVPNTileService.java +++ b/main/src/main/java/de/blinkt/openvpn/OpenVPNTileService.java @@ -17,9 +17,7 @@ import android.service.quicksettings.Tile;  import android.service.quicksettings.TileService;  import android.widget.Toast; -import java.util.Locale; - -import de.blinkt.openvpn.core.OpenVPNManagement; +import de.blinkt.openvpn.core.ConnectionStatus;  import de.blinkt.openvpn.core.OpenVPNService;  import de.blinkt.openvpn.core.ProfileManager;  import de.blinkt.openvpn.core.VpnStatus; @@ -107,10 +105,10 @@ public class OpenVPNTileService extends TileService implements VpnStatus.StateLi      }      @Override -    public void updateState(String state, String logmessage, int localizedResId, VpnStatus.ConnectionStatus level) { +    public void updateState(String state, String logmessage, int localizedResId, ConnectionStatus level) {          VpnProfile vpn;          Tile t = getQsTile(); -        if (level == VpnStatus.ConnectionStatus.LEVEL_AUTH_FAILED || level == VpnStatus.ConnectionStatus.LEVEL_NOTCONNECTED) { +        if (level == ConnectionStatus.LEVEL_AUTH_FAILED || level == ConnectionStatus.LEVEL_NOTCONNECTED) {              // No VPN connected, use stadnard VPN              vpn = getQSVPN();              if (vpn == null) { diff --git a/main/src/main/java/de/blinkt/openvpn/activities/DisconnectVPN.java b/main/src/main/java/de/blinkt/openvpn/activities/DisconnectVPN.java index e832c527..f63f5ed2 100644 --- a/main/src/main/java/de/blinkt/openvpn/activities/DisconnectVPN.java +++ b/main/src/main/java/de/blinkt/openvpn/activities/DisconnectVPN.java @@ -9,33 +9,36 @@ import android.app.Activity;  import android.app.AlertDialog;  import android.content.*;  import android.os.IBinder; +import android.os.Message; +import android.os.Messenger; +import android.os.RemoteException;  import de.blinkt.openvpn.LaunchVPN;  import de.blinkt.openvpn.R;  import de.blinkt.openvpn.VpnProfile;  import de.blinkt.openvpn.core.OpenVPNService;  import de.blinkt.openvpn.core.ProfileManager; +import de.blinkt.openvpn.core.VpnStatus;  /**   * Created by arne on 13.10.13.   */  public class DisconnectVPN extends Activity implements DialogInterface.OnClickListener, DialogInterface.OnCancelListener { -    protected OpenVPNService mService; - +    private Messenger mMessenger;      private ServiceConnection mConnection = new ServiceConnection() { +          @Override          public void onServiceConnected(ComponentName className,                                         IBinder service) { -            // We've bound to LocalService, cast the IBinder and get LocalService instance -            OpenVPNService.LocalBinder binder = (OpenVPNService.LocalBinder) service; -            mService = binder.getService(); +                mMessenger = new Messenger(service); +          }          @Override          public void onServiceDisconnected(ComponentName arg0) { -            mService =null; +            mMessenger = null;          }      }; @@ -72,8 +75,14 @@ public class DisconnectVPN extends Activity implements DialogInterface.OnClickLi          VpnProfile lastVPN = ProfileManager.getLastConnectedVpn();          if (which == DialogInterface.BUTTON_POSITIVE) {              ProfileManager.setConntectedVpnProfileDisconnected(this); -            if (mService != null && mService.getManagement() != null) -                mService.getManagement().stopVPN(false); +            if (mMessenger != null) { +                Message msg = Message.obtain(null, OpenVPNService.DISCONNECT_VPN_MSG); +                try { +                    mMessenger.send(msg); +                } catch (RemoteException e) { +                    VpnStatus.logException(e); +                } +            }          } else if (which == DialogInterface.BUTTON_NEUTRAL && lastVPN !=null) {              Intent intent = new Intent(this, LaunchVPN.class);              intent.putExtra(LaunchVPN.EXTRA_KEY, lastVPN.getUUID().toString()); diff --git a/main/src/main/java/de/blinkt/openvpn/api/ExternalOpenVPNService.java b/main/src/main/java/de/blinkt/openvpn/api/ExternalOpenVPNService.java index 00680d4f..ce72f346 100644 --- a/main/src/main/java/de/blinkt/openvpn/api/ExternalOpenVPNService.java +++ b/main/src/main/java/de/blinkt/openvpn/api/ExternalOpenVPNService.java @@ -36,12 +36,12 @@ import de.blinkt.openvpn.R;  import de.blinkt.openvpn.VpnProfile;
  import de.blinkt.openvpn.core.ConfigParser;
  import de.blinkt.openvpn.core.ConfigParser.ConfigParseError;
 +import de.blinkt.openvpn.core.ConnectionStatus;
  import de.blinkt.openvpn.core.OpenVPNService;
  import de.blinkt.openvpn.core.OpenVPNService.LocalBinder;
  import de.blinkt.openvpn.core.ProfileManager;
  import de.blinkt.openvpn.core.VPNLaunchHelper;
  import de.blinkt.openvpn.core.VpnStatus;
 -import de.blinkt.openvpn.core.VpnStatus.ConnectionStatus;
  import de.blinkt.openvpn.core.VpnStatus.StateListener;
  @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
 diff --git a/main/src/main/java/de/blinkt/openvpn/core/ConnectionStatus.java b/main/src/main/java/de/blinkt/openvpn/core/ConnectionStatus.java new file mode 100644 index 00000000..03d842e3 --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/core/ConnectionStatus.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2012-2016 Arne Schwabe + * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt + */ + +package de.blinkt.openvpn.core; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Created by arne on 08.11.16. + */ +public enum ConnectionStatus implements Parcelable { +    LEVEL_CONNECTED, +    LEVEL_VPNPAUSED, +    LEVEL_CONNECTING_SERVER_REPLIED, +    LEVEL_CONNECTING_NO_SERVER_REPLY_YET, +    LEVEL_NONETWORK, +    LEVEL_NOTCONNECTED, +    LEVEL_START, +    LEVEL_AUTH_FAILED, +    LEVEL_WAITING_FOR_USER_INPUT, +    UNKNOWN_LEVEL; + +    @Override +    public void writeToParcel(Parcel dest, int flags) { +        dest.writeInt(ordinal()); +    } + +    @Override +    public int describeContents() { +        return 0; +    } + +    public static final Creator<ConnectionStatus> CREATOR = new Creator<ConnectionStatus>() { +        @Override +        public ConnectionStatus createFromParcel(Parcel in) { +            return ConnectionStatus.values()[in.readInt()]; +        } + +        @Override +        public ConnectionStatus[] newArray(int size) { +            return new ConnectionStatus[size]; +        } +    }; +} diff --git a/main/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java b/main/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java index f35ebb23..4b31180a 100644 --- a/main/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java +++ b/main/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java @@ -16,19 +16,9 @@ import de.blinkt.openvpn.BuildConfig;  import de.blinkt.openvpn.R;  import de.blinkt.openvpn.core.PRNGFixes; -/* -@ReportsCrashes( -        formKey = "", -        formUri = "http://reports.blinkt.de/report-icsopenvpn", -        reportType = org.acra.sender.HttpSender.Type.JSON, -        httpMethod = org.acra.sender.HttpSender.Method.PUT, -        formUriBasicAuthLogin="report-icsopenvpn", -        formUriBasicAuthPassword="Tohd4neiF9Ai!!!!111eleven", -        mode = ReportingInteractionMode.TOAST, -        resToastText = R.string.crash_toast_text -) -*/  public class ICSOpenVPNApplication extends Application { +    private StatusListener mStatus; +      @Override      public void onCreate() {          super.onCreate(); @@ -39,5 +29,8 @@ public class ICSOpenVPNApplication extends Application {          }          VpnStatus.initLogCache(getApplicationContext().getCacheDir()); + +        mStatus = new StatusListener(); +        mStatus.init(getApplicationContext());      }  } diff --git a/main/src/main/java/de/blinkt/openvpn/core/LogItem.java b/main/src/main/java/de/blinkt/openvpn/core/LogItem.java index ebe884a8..823343a2 100644 --- a/main/src/main/java/de/blinkt/openvpn/core/LogItem.java +++ b/main/src/main/java/de/blinkt/openvpn/core/LogItem.java @@ -12,11 +12,8 @@ import android.content.pm.PackageManager;  import android.content.pm.Signature;  import android.os.Parcel;  import android.os.Parcelable; -import android.text.TextUtils; -import android.util.Log;  import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream;  import java.io.UnsupportedEncodingException;  import java.nio.BufferOverflowException;  import java.nio.ByteBuffer; diff --git a/main/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java b/main/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java index 03866962..818ef30a 100644 --- a/main/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java +++ b/main/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java @@ -49,12 +49,11 @@ import de.blinkt.openvpn.VpnProfile;  import de.blinkt.openvpn.activities.DisconnectVPN;  import de.blinkt.openvpn.activities.LogWindow;  import de.blinkt.openvpn.core.VpnStatus.ByteCountListener; -import de.blinkt.openvpn.core.VpnStatus.ConnectionStatus;  import de.blinkt.openvpn.core.VpnStatus.StateListener;  import static de.blinkt.openvpn.core.NetworkSpace.ipAddress; -import static de.blinkt.openvpn.core.VpnStatus.ConnectionStatus.LEVEL_CONNECTED; -import static de.blinkt.openvpn.core.VpnStatus.ConnectionStatus.LEVEL_WAITING_FOR_USER_INPUT; +import static de.blinkt.openvpn.core.ConnectionStatus.LEVEL_CONNECTED; +import static de.blinkt.openvpn.core.ConnectionStatus.LEVEL_WAITING_FOR_USER_INPUT;  public class OpenVPNService extends VpnService implements StateListener, Callback, ByteCountListener {      public static final String START_SERVICE = "de.blinkt.openvpn.START_SERVICE"; @@ -64,11 +63,11 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac      private static final String PAUSE_VPN = "de.blinkt.openvpn.PAUSE_VPN";      private static final String RESUME_VPN = "de.blinkt.openvpn.RESUME_VPN";      private static final int OPENVPN_STATUS = 1; +    public static final int DISCONNECT_VPN_MSG = 100;      private static boolean mNotificationAlwaysVisible = false;      private final Vector<String> mDnslist = new Vector<>();      private final NetworkSpace mRoutes = new NetworkSpace();      private final NetworkSpace mRoutesv6 = new NetworkSpace(); -    private final IBinder mBinder = new LocalBinder();      private Thread mProcessThread = null;      private VpnProfile mProfile;      private String mDomain = null; @@ -416,7 +415,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac      private void startOpenVPN() {          VpnStatus.logInfo(R.string.building_configration); -        VpnStatus.updateStateString("VPN_GENERATE_CONFIG", "", R.string.building_configration, VpnStatus.ConnectionStatus.LEVEL_START); +        VpnStatus.updateStateString("VPN_GENERATE_CONFIG", "", R.string.building_configration, ConnectionStatus.LEVEL_START);          try { @@ -1022,11 +1021,4 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac                  return "OPEN_BEFORE_CLOSE";          }      } - -    public class LocalBinder extends Binder { -        public OpenVPNService getService() { -            // Return this instance of LocalService so clients can call public methods -            return OpenVPNService.this; -        } -    }  } diff --git a/main/src/main/java/de/blinkt/openvpn/core/OpenVPNStatusService.java b/main/src/main/java/de/blinkt/openvpn/core/OpenVPNStatusService.java new file mode 100644 index 00000000..f84445ad --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/core/OpenVPNStatusService.java @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2012-2016 Arne Schwabe + * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt + */ + +package de.blinkt.openvpn.core; + +import android.app.Service; +import android.content.Intent; +import android.os.Handler; +import android.os.IBinder; +import android.os.Message; +import android.os.RemoteCallbackList; +import android.os.RemoteException; +import android.support.annotation.Nullable; +import android.util.Pair; + +import java.lang.ref.WeakReference; + +import de.blinkt.openvpn.api.ExternalOpenVPNService; +import de.blinkt.openvpn.api.IOpenVPNStatusCallback; + +/** + * Created by arne on 08.11.16. + */ + +public class OpenVPNStatusService extends Service implements VpnStatus.LogListener, VpnStatus.ByteCountListener, VpnStatus.StateListener { +    @Nullable +    @Override +    public IBinder onBind(Intent intent) { +        return mBinder; +    } + + +    static final RemoteCallbackList<IStatusCallbacks> mCallbacks = +            new RemoteCallbackList<>(); + +    @Override +    public void onCreate() { +        super.onCreate(); +        VpnStatus.addLogListener(this); +        VpnStatus.addByteCountListener(this); +        VpnStatus.addStateListener(this); +        mHandler.setService(this); + +    } + +    @Override +    public void onDestroy() { +        super.onDestroy(); + +        VpnStatus.removeLogListener(this); +        VpnStatus.removeByteCountListener(this); +        VpnStatus.removeStateListener(this); +        mCallbacks.kill(); + +    } + +    private static final IServiceStatus.Stub mBinder = new IServiceStatus.Stub() { + +        @Override +        public void registerStatusCallback(IStatusCallbacks cb) throws RemoteException { +            mCallbacks.register(cb); + +        } + +        @Override +        public void unregisterStatusCallback(IStatusCallbacks cb) throws RemoteException { +            mCallbacks.unregister(cb); +        } +    }; + +    @Override +    public void newLog(LogItem logItem) { +        Message msg = mHandler.obtainMessage(SEND_NEW_LOGITEM, logItem); +        msg.sendToTarget(); +    } + +    @Override +    public void updateByteCount(long in, long out, long diffIn, long diffOut) { +        Message msg = mHandler.obtainMessage(SEND_NEW_BYTECOUNT, Pair.create(in, out)); +        msg.sendToTarget(); +    } + +    class UpdateMessage { +        public String state; +        public String logmessage; +        public ConnectionStatus level; +        public int resId; + +        public UpdateMessage(String state, String logmessage, int resId, ConnectionStatus level) { +            this.state = state; +            this.resId = resId; +            this.logmessage = logmessage; +            this.level = level; +        } +    } + + +    @Override +    public void updateState(String state, String logmessage, int localizedResId, ConnectionStatus level) { + +        Message msg = mHandler.obtainMessage(SEND_NEW_STATE, new UpdateMessage(state, logmessage, localizedResId, level)); +        msg.sendToTarget(); +    } + +    private static final OpenVPNStatusHandler mHandler = new OpenVPNStatusHandler(); + +    private static final int SEND_NEW_LOGITEM = 100; +    private static final int SEND_NEW_STATE = 101; +    private static final int SEND_NEW_BYTECOUNT = 102; + +    static class OpenVPNStatusHandler extends Handler { +        WeakReference<OpenVPNStatusService> service = null; + +        private void setService(OpenVPNStatusService statusService) { +            service = new WeakReference<>(statusService); +        } + +        @Override +        public void handleMessage(Message msg) { + +            RemoteCallbackList<IStatusCallbacks> callbacks; +            if (service == null || service.get() == null) +                return; +            callbacks = service.get().mCallbacks; +            // Broadcast to all clients the new value. +            final int N = callbacks.beginBroadcast(); +            for (int i = 0; i < N; i++) { + +                try { +                    IStatusCallbacks broadcastItem = callbacks.getBroadcastItem(i); + +                    switch (msg.what) { +                        case SEND_NEW_LOGITEM: +                            broadcastItem.newLogItem((LogItem) msg.obj); +                            break; +                        case SEND_NEW_BYTECOUNT: +                            Pair<Long, Long> inout = (Pair<Long, Long>) msg.obj; +                            broadcastItem.updateByteCount(inout.first, inout.second); +                            break; +                        case SEND_NEW_STATE: +                            sendUpdate(broadcastItem, (UpdateMessage) msg.obj); +                            break; +                    } +                } catch (RemoteException e) { +                    // The RemoteCallbackList will take care of removing +                    // the dead object for us. +                } +            } +            callbacks.finishBroadcast(); +        } +    } + +    private static void sendUpdate(IStatusCallbacks broadcastItem, +                                   UpdateMessage um) throws RemoteException { +        broadcastItem.updateStateString(um.state, um.logmessage, um.resId, um.level); +    } +}
\ No newline at end of file diff --git a/main/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java b/main/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java index b2774861..e34897a8 100644 --- a/main/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java +++ b/main/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java @@ -19,13 +19,10 @@ import java.util.Collections;  import java.util.Date;
  import java.util.LinkedList;
  import java.util.Locale;
 -import java.util.Map;
 -import java.util.Map.Entry;
  import java.util.regex.Matcher;
  import java.util.regex.Pattern;
  import de.blinkt.openvpn.R;
 -import de.blinkt.openvpn.core.VpnStatus.ConnectionStatus;
  public class OpenVPNThread implements Runnable {
      private static final String DUMP_PATH_STRING = "Dump path: ";
 diff --git a/main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java b/main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java index bb0b2221..6f3f4165 100644 --- a/main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java +++ b/main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java @@ -32,7 +32,6 @@ import java.util.Vector;  import de.blinkt.openvpn.BuildConfig;
  import de.blinkt.openvpn.R;
  import de.blinkt.openvpn.VpnProfile;
 -import de.blinkt.openvpn.core.VpnStatus.ConnectionStatus;
  public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
 diff --git a/main/src/main/java/de/blinkt/openvpn/core/StatusListener.java b/main/src/main/java/de/blinkt/openvpn/core/StatusListener.java new file mode 100644 index 00000000..d0f845ee --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/core/StatusListener.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2012-2016 Arne Schwabe + * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt + */ + +package de.blinkt.openvpn.core; + +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.ServiceConnection; +import android.os.IBinder; +import android.os.RemoteException; + +/** + * Created by arne on 09.11.16. + */ + +public class StatusListener  { +    private ServiceConnection mConnection = new ServiceConnection() { + + +        @Override +        public void onServiceConnected(ComponentName className, +                                       IBinder service) { +            // We've bound to LocalService, cast the IBinder and get LocalService instance +            IServiceStatus serviceStatus = IServiceStatus.Stub.asInterface(service); +            try { +                /* Check if this a local service ... */ +                if (service.queryLocalInterface("de.blinkt.openvpn.core.IServiceStatus") == null) +                    serviceStatus.registerStatusCallback(mCallback); + +            } catch (RemoteException e) { +                e.printStackTrace(); +            } +        } + +        @Override +        public void onServiceDisconnected(ComponentName arg0) { + +        } + +    }; + +    void init(Context c) +    { + +        Intent intent = new Intent(c, OpenVPNStatusService.class); +        intent.setAction(OpenVPNService.START_SERVICE); + +        c.bindService(intent, mConnection, Context.BIND_AUTO_CREATE); + + +    } + + +    private IStatusCallbacks mCallback = new IStatusCallbacks.Stub() + +    { +        @Override +        public void newLogItem(LogItem item) throws RemoteException { +            VpnStatus.newLogItem(item); +        } + +        @Override +        public void updateStateString(String state, String msg, int resid, ConnectionStatus +                level) throws RemoteException { +            VpnStatus.updateStateString(state, msg, resid, level); +        } + +        @Override +        public void updateByteCount(long inBytes, long outBytes) throws RemoteException { +            VpnStatus.updateByteCount(inBytes, outBytes); +        } +    }; + +} diff --git a/main/src/main/java/de/blinkt/openvpn/core/VpnStatus.java b/main/src/main/java/de/blinkt/openvpn/core/VpnStatus.java index 13479cc7..5f6a30d6 100644 --- a/main/src/main/java/de/blinkt/openvpn/core/VpnStatus.java +++ b/main/src/main/java/de/blinkt/openvpn/core/VpnStatus.java @@ -123,18 +123,6 @@ public class VpnStatus {          mLogFileHandler.sendEmptyMessage(LogFileHandler.FLUSH_TO_DISK);      } -    public enum ConnectionStatus { -        LEVEL_CONNECTED, -        LEVEL_VPNPAUSED, -        LEVEL_CONNECTING_SERVER_REPLIED, -        LEVEL_CONNECTING_NO_SERVER_REPLY_YET, -        LEVEL_NONETWORK, -        LEVEL_NOTCONNECTED, -        LEVEL_START, -        LEVEL_AUTH_FAILED, -        LEVEL_WAITING_FOR_USER_INPUT, -        UNKNOWN_LEVEL -    }      public enum LogLevel {          INFO(2), @@ -341,7 +329,7 @@ public class VpnStatus {      } -    public static void updateStateString(String state, String msg) { +    static void updateStateString(String state, String msg) {          int rid = getLocalizedState(state);          ConnectionStatus level = getLevel(state);          updateStateString(state, msg, rid, level); @@ -384,7 +372,7 @@ public class VpnStatus {          newLogItem(new LogItem(LogLevel.DEBUG, resourceId, args));      } -    private static void newLogItem(LogItem logItem) { +    static void newLogItem(LogItem logItem) {          newLogItem(logItem, false);      } diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java b/main/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java index d3381bcb..067c7390 100644 --- a/main/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java +++ b/main/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java @@ -57,11 +57,11 @@ import de.blinkt.openvpn.VpnProfile;  import de.blinkt.openvpn.activities.DisconnectVPN;  import de.blinkt.openvpn.activities.MainActivity;  import de.blinkt.openvpn.activities.VPNPreferences; +import de.blinkt.openvpn.core.ConnectionStatus;  import de.blinkt.openvpn.core.OpenVPNManagement;  import de.blinkt.openvpn.core.OpenVPNService;  import de.blinkt.openvpn.core.ProfileManager;  import de.blinkt.openvpn.core.VpnStatus; -import de.blinkt.openvpn.core.VpnStatus.ConnectionStatus;  import de.blinkt.openvpn.core.LogItem;  import de.blinkt.openvpn.core.VpnStatus.LogListener;  import de.blinkt.openvpn.core.VpnStatus.StateListener; diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/VPNProfileList.java b/main/src/main/java/de/blinkt/openvpn/fragments/VPNProfileList.java index a2671376..de41d509 100644 --- a/main/src/main/java/de/blinkt/openvpn/fragments/VPNProfileList.java +++ b/main/src/main/java/de/blinkt/openvpn/fragments/VPNProfileList.java @@ -31,6 +31,7 @@ import de.blinkt.openvpn.activities.ConfigConverter;  import de.blinkt.openvpn.activities.DisconnectVPN;  import de.blinkt.openvpn.activities.FileSelect;  import de.blinkt.openvpn.activities.VPNPreferences; +import de.blinkt.openvpn.core.ConnectionStatus;  import de.blinkt.openvpn.core.ProfileManager;  import de.blinkt.openvpn.core.VpnStatus; @@ -55,7 +56,7 @@ public class VPNProfileList extends ListFragment implements OnClickListener, Vpn      private String mLastStatusMessage;      @Override -    public void updateState(String state, String logmessage, final int localizedResId, VpnStatus.ConnectionStatus level) { +    public void updateState(String state, String logmessage, final int localizedResId, ConnectionStatus level) {          getActivity().runOnUiThread(new Runnable() {              @Override              public void run() { | 
