From a1b858685d2e814ee7de9d287bf429c6deb31d2b Mon Sep 17 00:00:00 2001 From: cyBerta Date: Fri, 23 Mar 2018 14:37:56 +0100 Subject: #8876 refactoring in oder to move resultReceiver reference to runnable --- .../main/java/se/leap/bitmaskclient/eip/EIP.java | 546 +++++++++++---------- .../java/se/leap/bitmaskclient/eip/EipCommand.java | 4 + 2 files changed, 284 insertions(+), 266 deletions(-) (limited to 'app/src/main') diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java index 5dbf20c8..ed50999f 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java @@ -27,6 +27,7 @@ import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.os.ResultReceiver; +import android.os.SystemClock; import android.support.annotation.Nullable; import android.support.annotation.StringRes; import android.support.annotation.WorkerThread; @@ -90,10 +91,10 @@ public final class EIP extends Service implements Observer { ERRORS = "errors", ERROR_ID = "errorID"; - private volatile WeakReference mReceiverRef = new WeakReference<>(null); private volatile SharedPreferences preferences; private AtomicInteger processCounter; private volatile EipStatus eipStatus; + private final Object lock = new Object(); // Service connection to OpenVpnService, shared between threads private volatile OpenvpnServiceConnection openvpnServiceConnection; @@ -139,13 +140,11 @@ public final class EIP extends Service implements Observer { */ @Override public int onStartCommand(final Intent intent, int flags, int startId) { - processCounter.incrementAndGet(); + Log.d(TAG, "new process counter: " + processCounter.incrementAndGet()); final String action = intent.getAction(); if (action != null) { - if (intent.getParcelableExtra(EIP_RECEIVER) != null) { - mReceiverRef = new WeakReference<>((ResultReceiver) intent.getParcelableExtra(EIP_RECEIVER)); - } - new EipThread(this, action, intent).start(); + ResultReceiver resultReceiver = intent.getParcelableExtra(EIP_RECEIVER); + new EipThread(this, action, intent, resultReceiver).start(); } else { processCounter.decrementAndGet(); } @@ -153,246 +152,312 @@ public final class EIP extends Service implements Observer { } /** - * Initiates an EIP connection by selecting a gateway and preparing and sending an - * Intent to {@link de.blinkt.openvpn.LaunchVPN}. - * It also sets up early routes. + * Thread to handle the requests to this service */ - @SuppressLint("ApplySharedPref") - private void startEIP(boolean earlyRoutes) { - if (!eipStatus.isBlockingVpnEstablished() && earlyRoutes) { - earlyRoutes(); + class EipThread extends Thread { + EipThread(EIP eipReference, String action, Intent startIntent, ResultReceiver resultReceiver) { + super(new EipRunnable(eipReference, action, startIntent, resultReceiver)); } + } + + /** + * Runnable to be used in the EipThread class + */ + class EipRunnable implements Runnable { + private String action; + private EIP eipReference; + private Intent intent; + + private WeakReference mReceiverRef = new WeakReference<>(null); + - Bundle result = new Bundle(); - if (!preferences.getBoolean(EIP_RESTART_ON_BOOT, false)){ - preferences.edit().putBoolean(EIP_RESTART_ON_BOOT, true).commit(); + EipRunnable(EIP eipReference, String action, Intent startIntent, ResultReceiver resultReceiver) { + super(); + this.action = action; + this.eipReference = eipReference; + this.intent = startIntent; + this.mReceiverRef = new WeakReference(resultReceiver); } - GatewaysManager gatewaysManager = gatewaysFromPreferences(); - if (!isVPNCertificateValid()){ - setErrorResult(result, vpn_certificate_is_invalid, ERROR_INVALID_VPN_CERTIFICATE.toString()); - tellToReceiverOrBroadcast(EIP_ACTION_START, RESULT_CANCELED, result); - return; + /** + * select correct function to call based upon transmitted action + * after completing check if no other thread is running + * if no other thread is running terminate the EIP service + */ + @Override + public void run() { + Log.d(TAG, "new EIP thread started!"); + switch (action) { + case EIP_ACTION_START: + boolean earlyRoutes = intent.getBooleanExtra(EIP_EARLY_ROUTES, true); + startEIP(earlyRoutes); + break; + case EIP_ACTION_START_ALWAYS_ON_VPN: + startEIPAlwaysOnVpn(); + break; + case EIP_ACTION_STOP: + stopEIP(); + break; + case EIP_ACTION_IS_RUNNING: + isRunning(); + break; + case EIP_ACTION_CHECK_CERT_VALIDITY: + checkVPNCertificateValidity(); + break; + } + if (processCounter.decrementAndGet() == 0) { + Log.d(TAG, "no more running EIP threads!"); + eipReference.stopSelf(); + } } - Gateway gateway = gatewaysManager.select(); - if (gateway != null && gateway.getProfile() != null) { - launchActiveGateway(gateway); - tellToReceiverOrBroadcast(EIP_ACTION_START, RESULT_OK); - } else - tellToReceiverOrBroadcast(EIP_ACTION_START, RESULT_CANCELED); - } + /* Initiates an EIP connection by selecting a gateway and preparing and sending an + * Intent to {@link de.blinkt.openvpn.LaunchVPN}. + * It also sets up early routes. + */ + @SuppressLint("ApplySharedPref") + private void startEIP(boolean earlyRoutes) { + if (!eipStatus.isBlockingVpnEstablished() && earlyRoutes) { + earlyRoutes(); + } - /** - * Tries to start the last used vpn profile when the OS was rebooted and always-on-VPN is enabled. - * The {@link OnBootReceiver} will care if there is no profile. - */ - private void startEIPAlwaysOnVpn() { - Log.d(TAG, "startEIPAlwaysOnVpn vpn"); + Bundle result = new Bundle(); + if (!preferences.getBoolean(EIP_RESTART_ON_BOOT, false)) { + preferences.edit().putBoolean(EIP_RESTART_ON_BOOT, true).commit(); + } - GatewaysManager gatewaysManager = gatewaysFromPreferences(); - Gateway gateway = gatewaysManager.select(); + GatewaysManager gatewaysManager = gatewaysFromPreferences(); + if (!isVPNCertificateValid()) { + setErrorResult(result, vpn_certificate_is_invalid, ERROR_INVALID_VPN_CERTIFICATE.toString()); + tellToReceiverOrBroadcast(EIP_ACTION_START, RESULT_CANCELED, result); + return; + } - if (gateway != null && gateway.getProfile() != null) { - Log.d(TAG, "startEIPAlwaysOnVpn eip launch avtive gateway vpn"); - launchActiveGateway(gateway); - } else { - Log.d(TAG, "startEIPAlwaysOnVpn no active profile available!"); + Gateway gateway = gatewaysManager.select(); + if (gateway != null && gateway.getProfile() != null) { + launchActiveGateway(gateway); + tellToReceiverOrBroadcast(EIP_ACTION_START, RESULT_OK); + } else + tellToReceiverOrBroadcast(EIP_ACTION_START, RESULT_CANCELED); } - } - /** - * Early routes are routes that block traffic until a new - * VpnService is started properly. - */ - private void earlyRoutes() { - Intent voidVpnLauncher = new Intent(getApplicationContext(), VoidVpnLauncher.class); - voidVpnLauncher.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - startActivity(voidVpnLauncher); - } + /** + * Tries to start the last used vpn profile when the OS was rebooted and always-on-VPN is enabled. + * The {@link OnBootReceiver} will care if there is no profile. + */ + private void startEIPAlwaysOnVpn() { + Log.d(TAG, "startEIPAlwaysOnVpn vpn"); - /** - * starts the VPN and connects to the given gateway - * @param gateway to connect to - */ - private void launchActiveGateway(Gateway gateway) { - Intent intent = new Intent(this, LaunchVPN.class); - intent.setAction(Intent.ACTION_MAIN); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.putExtra(LaunchVPN.EXTRA_HIDELOG, true); - intent.putExtra(LaunchVPN.EXTRA_TEMP_VPN_PROFILE, gateway.getProfile()); - startActivity(intent); - } + GatewaysManager gatewaysManager = gatewaysFromPreferences(); + Gateway gateway = gatewaysManager.select(); - /** - * Stop VPN - * First checks if the OpenVpnConnection is open then - * terminates EIP if currently connected or connecting - */ - @WorkerThread - private void stopEIP() { - int resultCode = stop() ? RESULT_OK : RESULT_CANCELED; - tellToReceiverOrBroadcast(EIP_ACTION_STOP, resultCode); - } + if (gateway != null && gateway.getProfile() != null) { + Log.d(TAG, "startEIPAlwaysOnVpn eip launch avtive gateway vpn"); + launchActiveGateway(gateway); + } else { + Log.d(TAG, "startEIPAlwaysOnVpn no active profile available!"); + } + } - /** - * Checks the last stored status notified by ics-openvpn - * Sends Activity.RESULT_CANCELED to the ResultReceiver that made the - * request if it's not connected, Activity.RESULT_OK otherwise. - */ - private void isRunning() { - int resultCode = (eipStatus.isConnected()) ? - RESULT_OK : - RESULT_CANCELED; - tellToReceiverOrBroadcast(EIP_ACTION_IS_RUNNING, resultCode); - } + /** + * Early routes are routes that block traffic until a new + * VpnService is started properly. + */ + private void earlyRoutes() { + Intent voidVpnLauncher = new Intent(getApplicationContext(), VoidVpnLauncher.class); + voidVpnLauncher.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(voidVpnLauncher); + } - /** - * read eipServiceJson from preferences and parse Gateways - * @return GatewaysManager - */ - private GatewaysManager gatewaysFromPreferences() { - GatewaysManager gatewaysManager = new GatewaysManager(this, preferences); - gatewaysManager.configureFromPreferences(); - return gatewaysManager; - } + /** + * starts the VPN and connects to the given gateway + * + * @param gateway to connect to + */ + private void launchActiveGateway(Gateway gateway) { + Intent intent = new Intent(eipReference, LaunchVPN.class); + intent.setAction(Intent.ACTION_MAIN); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.putExtra(LaunchVPN.EXTRA_HIDELOG, true); + intent.putExtra(LaunchVPN.EXTRA_TEMP_VPN_PROFILE, gateway.getProfile()); + startActivity(intent); + } - /** - * read VPN certificate from preferences and check it - * broadcast result - */ - private void checkVPNCertificateValidity() { - int resultCode = isVPNCertificateValid() ? - RESULT_OK : - RESULT_CANCELED; - tellToReceiverOrBroadcast(EIP_ACTION_CHECK_CERT_VALIDITY, resultCode); - } + /** + * Stop VPN + * First checks if the OpenVpnConnection is open then + * terminates EIP if currently connected or connecting + */ + private void stopEIP() { + int resultCode = stop() ? RESULT_OK : RESULT_CANCELED; + tellToReceiverOrBroadcast(EIP_ACTION_STOP, resultCode); + } - /** - * read VPN certificate from preferences and check it - * @return true if VPN certificate is valid false otherwise - */ - private boolean isVPNCertificateValid() { - VpnCertificateValidator validator = new VpnCertificateValidator(preferences.getString(PROVIDER_VPN_CERTIFICATE, "")); - return validator.isValid(); - } + /** + * Checks the last stored status notified by ics-openvpn + * Sends Activity.RESULT_CANCELED to the ResultReceiver that made the + * request if it's not connected, Activity.RESULT_OK otherwise. + */ + private void isRunning() { + int resultCode = (eipStatus.isConnected()) ? + RESULT_OK : + RESULT_CANCELED; + tellToReceiverOrBroadcast(EIP_ACTION_IS_RUNNING, resultCode); + } - /** - * send resultCode and resultData to receiver or - * broadcast the result if no receiver is defined - * @param action the action that has been performed - * @param resultCode RESULT_OK if action was successful RESULT_CANCELED otherwise - * @param resultData other data to broadcast or return to receiver - */ - private void tellToReceiverOrBroadcast(String action, int resultCode, Bundle resultData) { - resultData.putString(EIP_REQUEST, action); - if (mReceiverRef.get() != null) { - mReceiverRef.get().send(resultCode, resultData); - } else { - broadcastEvent(resultCode, resultData); + /** + * read eipServiceJson from preferences and parse Gateways + * + * @return GatewaysManager + */ + private GatewaysManager gatewaysFromPreferences() { + GatewaysManager gatewaysManager = new GatewaysManager(eipReference, preferences); + gatewaysManager.configureFromPreferences(); + return gatewaysManager; } - } - /** - * send resultCode and resultData to receiver or - * broadcast the result if no receiver is defined - * @param action the action that has been performed - * @param resultCode RESULT_OK if action was successful RESULT_CANCELED otherwise - */ - private void tellToReceiverOrBroadcast(String action, int resultCode) { - tellToReceiverOrBroadcast(action, resultCode, new Bundle()); - } + /** + * read VPN certificate from preferences and check it + * broadcast result + */ + private void checkVPNCertificateValidity() { + int resultCode = isVPNCertificateValid() ? + RESULT_OK : + RESULT_CANCELED; + tellToReceiverOrBroadcast(EIP_ACTION_CHECK_CERT_VALIDITY, resultCode); + } - /** - * broadcast result - * @param resultCode RESULT_OK if action was successful RESULT_CANCELED otherwise - * @param resultData other data to broadcast or return to receiver - */ - private void broadcastEvent(int resultCode , Bundle resultData) { - Intent intentUpdate = new Intent(BROADCAST_EIP_EVENT); - intentUpdate.addCategory(CATEGORY_DEFAULT); - intentUpdate.putExtra(BROADCAST_RESULT_CODE, resultCode); - intentUpdate.putExtra(BROADCAST_RESULT_KEY, resultData); - Log.d(TAG, "sending broadcast"); - LocalBroadcastManager.getInstance(this).sendBroadcast(intentUpdate); - } + /** + * read VPN certificate from preferences and check it + * + * @return true if VPN certificate is valid false otherwise + */ + private boolean isVPNCertificateValid() { + VpnCertificateValidator validator = new VpnCertificateValidator(preferences.getString(PROVIDER_VPN_CERTIFICATE, "")); + return validator.isValid(); + } + /** + * send resultCode and resultData to receiver or + * broadcast the result if no receiver is defined + * + * @param action the action that has been performed + * @param resultCode RESULT_OK if action was successful RESULT_CANCELED otherwise + * @param resultData other data to broadcast or return to receiver + */ + private void tellToReceiverOrBroadcast(String action, int resultCode, Bundle resultData) { + resultData.putString(EIP_REQUEST, action); + if (mReceiverRef.get() != null) { + mReceiverRef.get().send(resultCode, resultData); + } else { + broadcastEvent(resultCode, resultData); + } + } - /** - * helper function to add error to result bundle - * @param result - result of an action - * @param errorMessageId - id of string resource describing the error - * @param errorId - MainActivityErrorDialog DownloadError id - */ - void setErrorResult(Bundle result, @StringRes int errorMessageId, String errorId) { - JSONObject errorJson = new JSONObject(); - try { - errorJson.put(ERRORS, getResources().getString(errorMessageId)); - errorJson.put(ERROR_ID, errorId); - } catch (JSONException e) { - e.printStackTrace(); + /** + * send resultCode and resultData to receiver or + * broadcast the result if no receiver is defined + * + * @param action the action that has been performed + * @param resultCode RESULT_OK if action was successful RESULT_CANCELED otherwise + */ + private void tellToReceiverOrBroadcast(String action, int resultCode) { + tellToReceiverOrBroadcast(action, resultCode, new Bundle()); } - result.putString(ERRORS, errorJson.toString()); - result.putBoolean(BROADCAST_RESULT_KEY, false); - } + /** + * broadcast result + * + * @param resultCode RESULT_OK if action was successful RESULT_CANCELED otherwise + * @param resultData other data to broadcast or return to receiver + */ + private void broadcastEvent(int resultCode, Bundle resultData) { + Intent intentUpdate = new Intent(BROADCAST_EIP_EVENT); + intentUpdate.addCategory(CATEGORY_DEFAULT); + intentUpdate.putExtra(BROADCAST_RESULT_CODE, resultCode); + intentUpdate.putExtra(BROADCAST_RESULT_KEY, resultData); + Log.d(TAG, "sending broadcast"); + LocalBroadcastManager.getInstance(eipReference).sendBroadcast(intentUpdate); + } - /** - * disable Bitmask starting on after phone reboot - * then stop VPN - */ - @WorkerThread - private boolean stop() { - preferences.edit().putBoolean(EIP_RESTART_ON_BOOT, false).apply(); - if (eipStatus.isBlockingVpnEstablished()) { - stopBlockingVpn(); + + /** + * helper function to add error to result bundle + * + * @param result - result of an action + * @param errorMessageId - id of string resource describing the error + * @param errorId - MainActivityErrorDialog DownloadError id + */ + void setErrorResult(Bundle result, @StringRes int errorMessageId, String errorId) { + JSONObject errorJson = new JSONObject(); + try { + errorJson.put(ERRORS, getResources().getString(errorMessageId)); + errorJson.put(ERROR_ID, errorId); + } catch (JSONException e) { + e.printStackTrace(); + } + result.putString(ERRORS, errorJson.toString()); + result.putBoolean(BROADCAST_RESULT_KEY, false); } - return disconnect(); - } - /** - * stop void vpn from blocking internet - */ - private void stopBlockingVpn() { - Log.d(TAG, "stop VoidVpn!"); - Intent stopVoidVpnIntent = new Intent(this, VoidVpnService.class); - stopVoidVpnIntent.setAction(EIP_ACTION_STOP_BLOCKING_VPN); - startService(stopVoidVpnIntent); - } + /** + * disable Bitmask starting on after phone reboot + * then stop VPN + */ + private boolean stop() { + preferences.edit().putBoolean(EIP_RESTART_ON_BOOT, false).apply(); + if (eipStatus.isBlockingVpnEstablished()) { + stopBlockingVpn(); + } + return disconnect(); + } - /** - * creates a OpenVpnServiceConnection if necessary - * then terminates OpenVPN - */ - @WorkerThread - private boolean disconnect() { - try { - initOpenVpnServiceConnection(); - } catch (InterruptedException | IllegalStateException e) { - return false; + /** + * stop void vpn from blocking internet + */ + private void stopBlockingVpn() { + Log.d(TAG, "stop VoidVpn!"); + Intent stopVoidVpnIntent = new Intent(eipReference, VoidVpnService.class); + stopVoidVpnIntent.setAction(EIP_ACTION_STOP_BLOCKING_VPN); + startService(stopVoidVpnIntent); } - ProfileManager.setConntectedVpnProfileDisconnected(this); - try { - return openvpnServiceConnection.getService().stopVPN(false); - } catch (RemoteException e) { - VpnStatus.logException(e); + + /** + * creates a OpenVpnServiceConnection if necessary + * then terminates OpenVPN + */ + private boolean disconnect() { + try { + initOpenVpnServiceConnection(); + } catch (InterruptedException | IllegalStateException e) { + return false; + } + + ProfileManager.setConntectedVpnProfileDisconnected(eipReference); + try { + return openvpnServiceConnection.getService().stopVPN(false); + } catch (RemoteException e) { + VpnStatus.logException(e); + } + return false; } - return false; - } - /** - * Assigns a new OpenvpnServiceConnection to EIP's member variable openvpnServiceConnection. - * Only one thread at a time can create the service connection, that will be shared between threads - * - * @throws InterruptedException thrown if thread gets interrupted - * @throws IllegalStateException thrown if this method was not called from a background thread - */ - @WorkerThread - private synchronized void initOpenVpnServiceConnection() throws InterruptedException, IllegalStateException { - if (openvpnServiceConnection == null) { - openvpnServiceConnection = new OpenvpnServiceConnection(this); + /** + * Assigns a new OpenvpnServiceConnection to EIP's member variable openvpnServiceConnection. + * Only one thread at a time can create the service connection, that will be shared between threads + * + * @throws InterruptedException thrown if thread gets interrupted + * @throws IllegalStateException thrown if this method was not called from a background thread + */ + private void initOpenVpnServiceConnection() throws InterruptedException, IllegalStateException { + synchronized (lock) { + if (openvpnServiceConnection == null) { + Log.d(TAG, "serviceConnection is still null"); + openvpnServiceConnection = new OpenvpnServiceConnection(eipReference); + } + } } } @@ -414,7 +479,7 @@ public final class EIP extends Service implements Observer { initSynchronizedServiceConnection(context); } - private void initSynchronizedServiceConnection(Context context) throws InterruptedException { + private void initSynchronizedServiceConnection(final Context context) throws InterruptedException { final BlockingQueue blockingQueue = new LinkedBlockingQueue<>(1); this.serviceConnection = new ServiceConnection() { volatile boolean mConnectedAtLeastOnce = false; @@ -422,6 +487,7 @@ public final class EIP extends Service implements Observer { if (!mConnectedAtLeastOnce) { mConnectedAtLeastOnce = true; try { + Log.d(TAG, "serviceConnection connected! ProcessCounter: " + ((EIP) context).processCounter.get()); blockingQueue.put(IOpenVPNServiceInternal.Stub.asInterface(service)); } catch (InterruptedException e) { e.printStackTrace(); @@ -429,6 +495,7 @@ public final class EIP extends Service implements Observer { } } @Override public void onServiceDisconnected(ComponentName name) { + Log.d(TAG, "serviceConnection disconnected! ProcessCounter: " + ((EIP) context).processCounter.get()); } }; @@ -447,58 +514,5 @@ public final class EIP extends Service implements Observer { } } - /** - * Thread to handle the requests to this service - */ - class EipThread extends Thread { - EipThread(EIP eipReference, String action, Intent startIntent) { - super(new EipRunnable(eipReference, action, startIntent)); - } - } - - /** - * Runnable to be used in the EipThread class - */ - class EipRunnable implements Runnable { - private String action; - private EIP eipReference; - private Intent intent; - - EipRunnable(EIP eipReference, String action, Intent startIntent){ - super(); - this.action = action; - this.eipReference = eipReference; - this.intent = startIntent; - } - - /** - * select correct function to call based upon transmitted action - * after completing check if no other thread is running - * if no other thread is running terminate the EIP service - */ - @Override - public void run() { - switch (action) { - case EIP_ACTION_START: - boolean earlyRoutes = intent.getBooleanExtra(EIP_EARLY_ROUTES, true); - startEIP(earlyRoutes); - break; - case EIP_ACTION_START_ALWAYS_ON_VPN: - startEIPAlwaysOnVpn(); - break; - case EIP_ACTION_STOP: - stopEIP(); - break; - case EIP_ACTION_IS_RUNNING: - isRunning(); - break; - case EIP_ACTION_CHECK_CERT_VALIDITY: - checkVPNCertificateValidity(); - break; - } - if (processCounter.decrementAndGet() == 0) { - eipReference.stopSelf(); - } - } - } } + diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EipCommand.java b/app/src/main/java/se/leap/bitmaskclient/eip/EipCommand.java index d2c8b4fc..5a6a98d8 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EipCommand.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EipCommand.java @@ -5,6 +5,7 @@ import android.content.Context; import android.content.Intent; import android.os.ResultReceiver; import android.support.annotation.NonNull; +import android.support.annotation.VisibleForTesting; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -50,6 +51,7 @@ public class EipCommand { execute(context, EIP_ACTION_START, null, baseIntent); } + @VisibleForTesting public static void startVPN(@NonNull Context context, ResultReceiver resultReceiver) { execute(context, EIP_ACTION_START, resultReceiver, null); } @@ -58,6 +60,7 @@ public class EipCommand { execute(context, EIP_ACTION_STOP); } + @VisibleForTesting public static void stopVPN(@NonNull Context context, ResultReceiver resultReceiver) { execute(context, EIP_ACTION_STOP, resultReceiver, null); } @@ -66,6 +69,7 @@ public class EipCommand { execute(context, EIP_ACTION_CHECK_CERT_VALIDITY); } + @VisibleForTesting public static void checkVpnCertificate(@NonNull Context context, ResultReceiver resultReceiver) { execute(context, EIP_ACTION_CHECK_CERT_VALIDITY, resultReceiver, null); } -- cgit v1.2.3