diff options
Diffstat (limited to 'app/src/fil/libre/repwifiapp/activities/ConnectionBoundActivity.java')
-rw-r--r-- | app/src/fil/libre/repwifiapp/activities/ConnectionBoundActivity.java | 282 |
1 files changed, 282 insertions, 0 deletions
diff --git a/app/src/fil/libre/repwifiapp/activities/ConnectionBoundActivity.java b/app/src/fil/libre/repwifiapp/activities/ConnectionBoundActivity.java new file mode 100644 index 0000000..4996024 --- /dev/null +++ b/app/src/fil/libre/repwifiapp/activities/ConnectionBoundActivity.java @@ -0,0 +1,282 @@ +// +// Copyright 2017, 2018 Filippo "Fil" Bergamo <fil.bergamo@riseup.net> +// +// This file is part of RepWifiApp. +// +// RepWifiApp is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// RepWifiApp is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with RepWifiApp. If not, see <http://www.gnu.org/licenses/>. +// +// ******************************************************************** + +package fil.libre.repwifiapp.activities; + +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.ServiceConnection; +import android.content.SharedPreferences; +import android.content.SharedPreferences.OnSharedPreferenceChangeListener; +import android.os.Bundle; +import android.os.Handler; +import android.os.IBinder; +import android.os.Message; +import android.os.Messenger; +import android.preference.PreferenceManager; +import fil.libre.repwifiapp.Prefs; +import fil.libre.repwifiapp.helpers.Logger; +import fil.libre.repwifiapp.network.AccessPointInfo; +import fil.libre.repwifiapp.network.ConnectionResult; +import fil.libre.repwifiapp.network.ConnectionStatus; +import fil.libre.repwifiapp.service.Channel; +import fil.libre.repwifiapp.service.ConnectionManagementService; + +/** + * Provides a base class for all activities that need to bind to the + * ConnectionManagementService. + */ +public class ConnectionBoundActivity extends MenuEnabledActivity implements + OnSharedPreferenceChangeListener { + + private IBinder svcBinder = null; + private Channel channel = null; + private ServiceConnection svcConn = null; + + + @Override + public void onStart() { + super.onStart(); + startConnectionService(); + registerPreferenceChangeListener(); + } + + protected boolean isServiceBound() { + return (channel != null); + } + + private void startConnectionService() { + + Intent startIntent = new Intent(this, ConnectionManagementService.class); + startIntent.setAction(ConnectionManagementService.ACTION_VOID); + startService(startIntent); + + if (channel != null) { + Logger.logDebug("ConnectionManagementService already bound"); + return; + } + + try { + + if (svcConn == null) { + + svcConn = new ServiceConnection() { + + public void onServiceConnected(ComponentName className, + android.os.IBinder service) { + ConnectionBoundActivity.this.initChannel(service); + } + + public void onServiceDisconnected(ComponentName className) { + ConnectionBoundActivity.this.channel = null; + ConnectionBoundActivity.this.svcBinder = null; + } + + }; + + } + + Intent intentGetService = new Intent(this, ConnectionManagementService.class); + if (!this.bindService(intentGetService, svcConn, Context.BIND_AUTO_CREATE)) { + Logger.logError("Failed to bind to ConnectionManagementService (bindService returned false)"); + return; + } + + } catch (Exception ex) { + Logger.logError("Exception while bounding to inner connectivity management service.", + ex); + } + + } + + private void initChannel(IBinder service) { + ConnectionBoundActivity.this.svcBinder = service; + ConnectionBoundActivity.this.channel = new Channel(this, new Messenger(service), + new Messenger(new ResponseHandler())); + ConnectionBoundActivity.this.onManagementServiceConnected(); + } + + protected void onManagementServiceConnected() { + sendCmdPrefChanged(Prefs.PREF_MONITOR_NET_STATE); + } + + protected boolean sendCmdStartConnect(AccessPointInfo network) { + if (channel == null) { + return false; + } + return channel.sendMsg(ConnectionManagementService.CMD_START_CONNECT, network, + Channel.PAYLOAD_APINFO); + } + + protected boolean sendCmdAbortConnection() { + return sendMsgIfChannelConnected(ConnectionManagementService.CMD_ABORT_CONNECTION); + } + + protected boolean sendCmdDisconnect() { + return sendMsgIfChannelConnected(ConnectionManagementService.CMD_DISCONNECT); + } + + protected boolean sendCmdGetAvailableNetworks() { + return sendMsgIfChannelConnected(ConnectionManagementService.CMD_GET_AVAILABLE_NETWORKS); + } + + protected boolean sendCmdStartMonitoringConnectionStatus() { + return sendMsgIfChannelConnected(ConnectionManagementService.CMD_START_MONITOR_CONNECTION_STATUS); + } + + protected boolean sendCmdStopMonitoringConnectionStatus() { + return sendMsgIfChannelConnected(ConnectionManagementService.CMD_STOP_MONITOR_CONNECTION_STATUS); + } + + protected boolean requestStatusUpdate() { + return sendMsgIfChannelConnected(ConnectionManagementService.CMD_STATUS_UPDATE); + } + + protected boolean sendCmdAutoconnect() { + return sendMsgIfChannelConnected(ConnectionManagementService.CMD_AUTOCONNECT); + } + + private boolean sendCmdPrefChanged(String prefname){ + if (channel == null){ + return false; + } + Bundle b = new Bundle(); + b.putString(Channel.PAYLOAD_PREFKEY, prefname); + return channel.sendMsg(ConnectionManagementService.CMD_PREF_CHANGED, b, 0); + } + + private void sendCmdUnbind() { + sendMsgIfChannelConnected(ConnectionManagementService.CMD_CLIENT_UNBINDING); + } + + private boolean sendMsgIfChannelConnected(int what) { + return sendMsgIfChannelConnected(what, 0); + } + + private boolean sendMsgIfChannelConnected(int what, int arg1) { + if (channel == null) { + return false; + } + return channel.sendMsg(what, null, arg1); + } + + protected void onMsgStatusChange(ConnectionStatus status) { + } + + protected void onMsgConnectionResult(ConnectionResult connres) { + } + + protected void onMsgAvailableNetworks(AccessPointInfo[] infos) { + } + + protected void onMsgAutoconnectReport(AccessPointInfo[] infos) { + } + + protected void onMsgDisconnectReport(ConnectionStatus status) { + } + + private class ResponseHandler extends Handler { + + public void handleMessage(Message msg) { + switch (msg.what) { + + case ConnectionManagementService.MSG_STATUS_CHANGE: + Logger.logDebug("Received status update from the management service"); + ConnectionStatus c = channel.getConnectionStatusPayload(msg); + onMsgStatusChange(c); + break; + + case ConnectionManagementService.MSG_CONNECTION_RESULT: + Logger.logDebug("Received connection result from management service"); + ConnectionResult r = channel.getConnectionResultPayload(msg); + onMsgConnectionResult(r); + break; + + case ConnectionManagementService.MSG_AVAILABLE_NETWORKS: + Logger.logDebug("Received available networks from management service"); + onMsgAvailableNetworks(channel.getApinfoArrayPayload(msg)); + break; + + case ConnectionManagementService.MSG_AUTOCONNECT_REPORT: + Logger.logDebug("Received autoconnect report from management service"); + onMsgAutoconnectReport(channel.getApinfoArrayPayload(msg)); + break; + + case ConnectionManagementService.MSG_DISCONNECT_REPORT: + Logger.logDebug("Received disconnect report from management service"); + onMsgDisconnectReport(channel.getConnectionStatusPayload(msg)); + break; + + default: + Logger.logError("Received response from connection management service with unknown what: " + + msg.what); + } + } + + } + + private void registerPreferenceChangeListener() { + + SharedPreferences prefs = PreferenceManager + .getDefaultSharedPreferences(getApplicationContext()); + prefs.registerOnSharedPreferenceChangeListener(this); + + } + + private void unregisterPreferenceChangeListener() { + SharedPreferences prefs = PreferenceManager + .getDefaultSharedPreferences(getApplicationContext()); + prefs.unregisterOnSharedPreferenceChangeListener(this); + } + + + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { + + if (sharedPreferences == null) { + return; + } + + sharedPreferences.edit().commit(); + Prefs.commit(getApplicationContext()); + sendCmdPrefChanged(key); + + } + + protected void unbindFromService() { + sendCmdUnbind(); + if (svcBinder != null && svcConn != null && channel != null) { + unbindService(svcConn); + } + } + + @Override + protected void onStop() { + super.onStop(); + } + + @Override + public void onDestroy() { + unregisterPreferenceChangeListener(); + unbindFromService(); + super.onDestroy(); + } +} |