aboutsummaryrefslogtreecommitdiffstats
path: root/app/src/fil/libre/repwifiapp/activities/ConnectionBoundActivity.java
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/fil/libre/repwifiapp/activities/ConnectionBoundActivity.java')
-rw-r--r--app/src/fil/libre/repwifiapp/activities/ConnectionBoundActivity.java282
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();
+ }
+}