clean-up of code to make service more long-lived and stable
This commit is contained in:
parent
695b5c32f1
commit
ec9204a5f3
|
@ -82,6 +82,8 @@ public class Orbot extends ActionBarActivity implements TorConstants, OnLongClic
|
||||||
private SharedPreferences mPrefs = null;
|
private SharedPreferences mPrefs = null;
|
||||||
|
|
||||||
private boolean autoStartFromIntent = false;
|
private boolean autoStartFromIntent = false;
|
||||||
|
|
||||||
|
private final static long INIT_DELAY = 100;
|
||||||
|
|
||||||
/** Called when the activity is first created. */
|
/** Called when the activity is first created. */
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
@ -106,12 +108,23 @@ public class Orbot extends ActionBarActivity implements TorConstants, OnLongClic
|
||||||
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
|
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
|
||||||
new IntentFilter("log"));
|
new IntentFilter("log"));
|
||||||
|
|
||||||
startService(TorServiceConstants.CMD_INIT);
|
mHandler.postDelayed(new Runnable ()
|
||||||
|
{
|
||||||
|
|
||||||
|
public void run ()
|
||||||
|
{
|
||||||
|
startService(TorServiceConstants.CMD_INIT);
|
||||||
|
}
|
||||||
|
},INIT_DELAY);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Our handler for received Intents. This will be called whenever an Intent
|
// Our handler for received Intents. This will be called whenever an Intent
|
||||||
// with an action named "custom-event-name" is broadcasted.
|
// with an action named "custom-event-name" is broadcasted.
|
||||||
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
|
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
// Get extra data included in the Intent
|
// Get extra data included in the Intent
|
||||||
|
@ -724,15 +737,6 @@ public class Orbot extends ActionBarActivity implements TorConstants, OnLongClic
|
||||||
updateStatus("");
|
updateStatus("");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see android.app.Activity#onStop()
|
|
||||||
*/
|
|
||||||
protected void onStop() {
|
|
||||||
super.onStop();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Launch the system activity for Uri viewing with the provided url
|
* Launch the system activity for Uri viewing with the provided url
|
||||||
|
@ -1117,73 +1121,7 @@ public class Orbot extends ActionBarActivity implements TorConstants, OnLongClic
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread threadUpdater = null;
|
|
||||||
boolean mKeepUpdating = false;
|
|
||||||
|
|
||||||
public void initUpdates ()
|
|
||||||
{
|
|
||||||
mKeepUpdating = true;
|
|
||||||
|
|
||||||
if (threadUpdater == null || !threadUpdater.isAlive())
|
|
||||||
{
|
|
||||||
threadUpdater = new Thread(new Runnable()
|
|
||||||
{
|
|
||||||
|
|
||||||
public void run ()
|
|
||||||
{
|
|
||||||
|
|
||||||
while (mKeepUpdating)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
if (mService != null)
|
|
||||||
{
|
|
||||||
for (String log : mService.getLog())
|
|
||||||
{
|
|
||||||
Message msg = mHandler.obtainMessage(TorServiceConstants.LOG_MSG);
|
|
||||||
msg.getData().putString(HANDLER_TOR_MSG, log);
|
|
||||||
mHandler.sendMessage(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (String status : mService.getStatusMessage())
|
|
||||||
{
|
|
||||||
Message msg = mHandler.obtainMessage(TorServiceConstants.STATUS_MSG);
|
|
||||||
msg.getData().putString(HANDLER_TOR_MSG, status);
|
|
||||||
mHandler.sendMessage(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mService != null)
|
|
||||||
{
|
|
||||||
long[] bws = mService.getBandwidth();
|
|
||||||
Message msg = mHandler.obtainMessage(TorServiceConstants.MESSAGE_TRAFFIC_COUNT);
|
|
||||||
msg.getData().putLong("download", bws[0]);
|
|
||||||
msg.getData().putLong("upload", bws[1]);
|
|
||||||
msg.getData().putLong("readTotal", bws[2]);
|
|
||||||
msg.getData().putLong("writeTotal", bws[3]);
|
|
||||||
mHandler.sendMessage(msg);
|
|
||||||
|
|
||||||
try { Thread.sleep(1000); }
|
|
||||||
catch (Exception e){}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mService != null)
|
|
||||||
torStatus = mService.getStatus();
|
|
||||||
}**/
|
|
||||||
}
|
|
||||||
catch (Exception re)
|
|
||||||
{
|
|
||||||
Log.e(TAG, "error getting service updates",re);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
threadUpdater.start();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -135,14 +135,15 @@ public class TorService extends Service implements TorServiceConstants, TorConst
|
||||||
private Builder mNotifyBuilder;
|
private Builder mNotifyBuilder;
|
||||||
private Notification mNotification;
|
private Notification mNotification;
|
||||||
private boolean mShowExpandedNotifications = false;
|
private boolean mShowExpandedNotifications = false;
|
||||||
|
private boolean mNotificationShowing = false;
|
||||||
|
|
||||||
private boolean mHasRoot = false;
|
private boolean mHasRoot = false;
|
||||||
private boolean mEnableTransparentProxy = false;
|
private boolean mEnableTransparentProxy = false;
|
||||||
private boolean mTransProxyAll = false;
|
private boolean mTransProxyAll = false;
|
||||||
private boolean mTransProxyTethering = false;
|
private boolean mTransProxyTethering = false;
|
||||||
private boolean mTransProxyNetworkRefresh = false;
|
private boolean mTransProxyNetworkRefresh = false;
|
||||||
|
|
||||||
private ExecutorService mExecutor = Executors.newCachedThreadPool();
|
private ExecutorService mExecutor = Executors.newFixedThreadPool(1);
|
||||||
|
|
||||||
public void debug(String msg)
|
public void debug(String msg)
|
||||||
{
|
{
|
||||||
|
@ -231,7 +232,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst
|
||||||
|
|
||||||
|
|
||||||
hmBuiltNodes.clear();
|
hmBuiltNodes.clear();
|
||||||
|
mNotificationShowing = false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,14 +328,17 @@ public class TorService extends Service implements TorServiceConstants, TorConst
|
||||||
mNotification.bigContentView = expandedView;
|
mNotification.bigContentView = expandedView;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mNotification == null && prefPersistNotifications)
|
if (prefPersistNotifications && (!mNotificationShowing))
|
||||||
{
|
{
|
||||||
startForeground(NOTIFY_ID, mNotification);
|
startForeground(NOTIFY_ID, mNotification);
|
||||||
|
logNotice("Set background service to FOREGROUND");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mNotificationManager.notify(NOTIFY_ID, mNotification);
|
mNotificationManager.notify(NOTIFY_ID, mNotification);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mNotificationShowing = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -401,6 +405,10 @@ public class TorService extends Service implements TorServiceConstants, TorConst
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.d(TAG, "Got null onStartCommand() intent");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
@ -412,7 +420,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTaskRemoved(Intent rootIntent) {
|
public void onTaskRemoved(Intent rootIntent) {
|
||||||
//logNotice("Orbot was swiped away... background service will keep running");
|
Log.d(TAG,"task removed");
|
||||||
|
|
||||||
Intent intent = new Intent( this, DummyActivity.class );
|
Intent intent = new Intent( this, DummyActivity.class );
|
||||||
intent.addFlags( Intent.FLAG_ACTIVITY_NEW_TASK );
|
intent.addFlags( Intent.FLAG_ACTIVITY_NEW_TASK );
|
||||||
|
@ -431,14 +439,17 @@ public class TorService extends Service implements TorServiceConstants, TorConst
|
||||||
@Override
|
@Override
|
||||||
public void onDestroy ()
|
public void onDestroy ()
|
||||||
{
|
{
|
||||||
super.onDestroy();
|
String msg = ("TorService is being DESTROYED... shutting down!");
|
||||||
|
|
||||||
logNotice("TorService is being destroyed... shutting down!");
|
Log.d(TAG, msg);
|
||||||
|
sendCallbackLogMessage(msg);
|
||||||
|
|
||||||
unregisterReceiver(mNetworkStateReceiver);
|
// unregisterReceiver(mNetworkStateReceiver);
|
||||||
|
|
||||||
clearNotifications ();
|
clearNotifications ();
|
||||||
|
|
||||||
|
super.onDestroy();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void stopTor ()
|
private void stopTor ()
|
||||||
|
@ -446,6 +457,8 @@ public class TorService extends Service implements TorServiceConstants, TorConst
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
Log.d(TAG,"Tor is stopping NOW");
|
||||||
|
|
||||||
shutdownTorProcess ();
|
shutdownTorProcess ();
|
||||||
|
|
||||||
//stop the foreground priority and make sure to remove the persistant notification
|
//stop the foreground priority and make sure to remove the persistant notification
|
||||||
|
@ -611,8 +624,9 @@ public class TorService extends Service implements TorServiceConstants, TorConst
|
||||||
if (mNotificationManager == null)
|
if (mNotificationManager == null)
|
||||||
{
|
{
|
||||||
|
|
||||||
IntentFilter mNetworkStateFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
|
// IntentFilter mNetworkStateFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
|
||||||
registerReceiver(mNetworkStateReceiver , mNetworkStateFilter);
|
// mNetworkStateFilter.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
|
||||||
|
// registerReceiver(mNetworkStateReceiver , mNetworkStateFilter);
|
||||||
|
|
||||||
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
|
|
||||||
|
@ -723,6 +737,10 @@ public class TorService extends Service implements TorServiceConstants, TorConst
|
||||||
extraLines.append("VirtualAddrNetwork 10.192.0.0/10").append('\n');
|
extraLines.append("VirtualAddrNetwork 10.192.0.0/10").append('\n');
|
||||||
extraLines.append("AutomapHostsOnResolve 1").append('\n');
|
extraLines.append("AutomapHostsOnResolve 1").append('\n');
|
||||||
|
|
||||||
|
|
||||||
|
extraLines.append("CircuitStreamTimeout 60").append('\n');
|
||||||
|
|
||||||
|
|
||||||
extraLines.append(prefs.getString("pref_custom_torrc", ""));
|
extraLines.append(prefs.getString("pref_custom_torrc", ""));
|
||||||
|
|
||||||
logNotice("updating torrc custom configuration...");
|
logNotice("updating torrc custom configuration...");
|
||||||
|
@ -802,20 +820,23 @@ public class TorService extends Service implements TorServiceConstants, TorConst
|
||||||
logNotice(getString(R.string.status_starting_up));
|
logNotice(getString(R.string.status_starting_up));
|
||||||
sendCallbackLogMessage(getString(R.string.status_starting_up));
|
sendCallbackLogMessage(getString(R.string.status_starting_up));
|
||||||
|
|
||||||
boolean success = runTorShellCmd();
|
Shell shellUser = Shell.startShell();
|
||||||
|
|
||||||
|
boolean success = runTorShellCmd(shellUser);
|
||||||
|
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
runPolipoShellCmd();
|
if (mPortHTTP != -1)
|
||||||
|
runPolipoShellCmd(shellUser);
|
||||||
|
|
||||||
if (mHasRoot && mEnableTransparentProxy)
|
if (mHasRoot && mEnableTransparentProxy)
|
||||||
{
|
{
|
||||||
Shell shell = Shell.startRootShell();
|
Shell shellRoot = Shell.startRootShell();
|
||||||
|
|
||||||
disableTransparentProxy(shell);
|
disableTransparentProxy(shellRoot);
|
||||||
enableTransparentProxy(shell);
|
enableTransparentProxy(shellRoot);
|
||||||
|
|
||||||
shell.close();
|
shellRoot.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
getHiddenServiceHostname ();
|
getHiddenServiceHostname ();
|
||||||
|
@ -825,6 +846,8 @@ public class TorService extends Service implements TorServiceConstants, TorConst
|
||||||
showToolbarNotification(getString(R.string.unable_to_start_tor), ERROR_NOTIFY_ID, R.drawable.ic_stat_notifyerr);
|
showToolbarNotification(getString(R.string.unable_to_start_tor), ERROR_NOTIFY_ID, R.drawable.ic_stat_notifyerr);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shellUser.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean flushTransparentProxyRules () throws Exception
|
private boolean flushTransparentProxyRules () throws Exception
|
||||||
|
@ -939,19 +962,14 @@ public class TorService extends Service implements TorServiceConstants, TorConst
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean runTorShellCmd() throws Exception
|
private boolean runTorShellCmd(Shell shell) throws Exception
|
||||||
{
|
{
|
||||||
|
|
||||||
Shell shellTor;
|
|
||||||
|
|
||||||
String torrcPath = new File(appBinHome, TORRC_ASSET_KEY).getCanonicalPath();
|
String torrcPath = new File(appBinHome, TORRC_ASSET_KEY).getCanonicalPath();
|
||||||
|
|
||||||
updateTorConfigFile();
|
updateTorConfigFile();
|
||||||
|
|
||||||
sendCallbackLogMessage(getString(R.string.status_starting_up));
|
sendCallbackLogMessage(getString(R.string.status_starting_up));
|
||||||
|
|
||||||
//start Tor in the background
|
|
||||||
shellTor = Shell.startShell();
|
|
||||||
|
|
||||||
String torCmdString = fileTor.getCanonicalPath()
|
String torCmdString = fileTor.getCanonicalPath()
|
||||||
+ " DataDirectory " + appCacheHome.getCanonicalPath()
|
+ " DataDirectory " + appCacheHome.getCanonicalPath()
|
||||||
|
@ -961,7 +979,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst
|
||||||
debug(torCmdString);
|
debug(torCmdString);
|
||||||
|
|
||||||
SimpleCommand shellTorCommand = new SimpleCommand(torCmdString + " --verify-config");
|
SimpleCommand shellTorCommand = new SimpleCommand(torCmdString + " --verify-config");
|
||||||
shellTor.add(shellTorCommand).waitForFinish();
|
shell.add(shellTorCommand).waitForFinish();
|
||||||
|
|
||||||
int exitCode = shellTorCommand.getExitCode();
|
int exitCode = shellTorCommand.getExitCode();
|
||||||
String output = shellTorCommand.getOutput();
|
String output = shellTorCommand.getOutput();
|
||||||
|
@ -974,7 +992,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst
|
||||||
}
|
}
|
||||||
|
|
||||||
shellTorCommand = new SimpleCommand(torCmdString);
|
shellTorCommand = new SimpleCommand(torCmdString);
|
||||||
shellTor.add(shellTorCommand).waitForFinish();
|
shell.add(shellTorCommand).waitForFinish();
|
||||||
|
|
||||||
exitCode = shellTorCommand.getExitCode();
|
exitCode = shellTorCommand.getExitCode();
|
||||||
output = shellTorCommand.getOutput();
|
output = shellTorCommand.getOutput();
|
||||||
|
@ -1007,8 +1025,6 @@ public class TorService extends Service implements TorServiceConstants, TorConst
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
shellTor.close();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1030,7 +1046,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void runPolipoShellCmd () throws Exception
|
private void runPolipoShellCmd (Shell shell) throws Exception
|
||||||
{
|
{
|
||||||
|
|
||||||
logNotice( "Starting polipo process");
|
logNotice( "Starting polipo process");
|
||||||
|
@ -1041,8 +1057,6 @@ public class TorService extends Service implements TorServiceConstants, TorConst
|
||||||
|
|
||||||
int attempts = 0;
|
int attempts = 0;
|
||||||
|
|
||||||
Shell shell = Shell.startShell();
|
|
||||||
|
|
||||||
if (polipoProcId == -1)
|
if (polipoProcId == -1)
|
||||||
{
|
{
|
||||||
log = new StringBuilder();
|
log = new StringBuilder();
|
||||||
|
@ -1071,8 +1085,6 @@ public class TorService extends Service implements TorServiceConstants, TorConst
|
||||||
|
|
||||||
logNotice("Polipo process id=" + polipoProcId);
|
logNotice("Polipo process id=" + polipoProcId);
|
||||||
|
|
||||||
shell.close();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int initControlConnection (int maxTries, boolean isReconnect) throws Exception, RuntimeException
|
private int initControlConnection (int maxTries, boolean isReconnect) throws Exception, RuntimeException
|
||||||
|
@ -1983,6 +1995,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst
|
||||||
private void sendCallbackStatusMessage (long upload, long download, long written, long read)
|
private void sendCallbackStatusMessage (long upload, long download, long written, long read)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
Intent intent = new Intent("log");
|
Intent intent = new Intent("log");
|
||||||
// You can also include some extra data.
|
// You can also include some extra data.
|
||||||
intent.putExtra("up",upload);
|
intent.putExtra("up",upload);
|
||||||
|
@ -2023,6 +2036,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst
|
||||||
* Another way to do this would be to use the Observer pattern by defining the
|
* Another way to do this would be to use the Observer pattern by defining the
|
||||||
* BroadcastReciever in the Android manifest.
|
* BroadcastReciever in the Android manifest.
|
||||||
*/
|
*/
|
||||||
|
/**
|
||||||
private final BroadcastReceiver mNetworkStateReceiver = new BroadcastReceiver() {
|
private final BroadcastReceiver mNetworkStateReceiver = new BroadcastReceiver() {
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
@ -2081,7 +2095,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};*/
|
||||||
|
|
||||||
private boolean processSettingsImpl () throws Exception
|
private boolean processSettingsImpl () throws Exception
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,9 +34,6 @@ import android.os.ParcelFileDescriptor;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.runjva.sourceforge.jsocks.protocol.ProxyServer;
|
|
||||||
import com.runjva.sourceforge.jsocks.server.ServerAuthenticatorNone;
|
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
|
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
|
||||||
public class OrbotVpnService extends VpnService implements Handler.Callback {
|
public class OrbotVpnService extends VpnService implements Handler.Callback {
|
||||||
private static final String TAG = "OrbotVpnService";
|
private static final String TAG = "OrbotVpnService";
|
||||||
|
@ -51,7 +48,7 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
|
||||||
private ParcelFileDescriptor mInterface;
|
private ParcelFileDescriptor mInterface;
|
||||||
|
|
||||||
private int mSocksProxyPort = 9999;
|
private int mSocksProxyPort = 9999;
|
||||||
private ProxyServer mProxyServer;
|
// private ProxyServer mProxyServer;
|
||||||
|
|
||||||
private final static int VPN_MTU = 1500;
|
private final static int VPN_MTU = 1500;
|
||||||
|
|
||||||
|
@ -76,29 +73,12 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
|
||||||
|
|
||||||
private void startSocksBypass ()
|
private void startSocksBypass ()
|
||||||
{
|
{
|
||||||
mThreadProxy = new Thread ()
|
|
||||||
{
|
|
||||||
public void run ()
|
|
||||||
{
|
|
||||||
|
|
||||||
try {
|
|
||||||
mProxyServer = new ProxyServer(new ServerAuthenticatorNone(null, null));
|
|
||||||
mProxyServer.setVpnService(OrbotVpnService.this);
|
|
||||||
mProxyServer.start(mSocksProxyPort, 5, InetAddress.getLocalHost());
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.d(TAG,"proxy server error: " + e.getLocalizedMessage(),e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
mThreadProxy.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
|
|
||||||
if (mProxyServer != null)
|
|
||||||
mProxyServer.stop();
|
|
||||||
|
|
||||||
if (mInterface != null)
|
if (mInterface != null)
|
||||||
try {
|
try {
|
||||||
|
|
Loading…
Reference in New Issue