Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/quite/humla.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Comminos <andrew@comminos.com>2015-10-25 00:27:15 +0300
committerAndrew Comminos <andrew@comminos.com>2015-10-25 00:27:15 +0300
commit36b4678a43060075f3a7d0e50ffbeacb57914596 (patch)
tree60b7968500c65cbc7a25b6336caace32c99439b0
parent1e9cdc6e3ef15775e6da7423e2f83f775a688a94 (diff)
parent28495cdc35bf8a2e680ce3dc8eab228a1bb7565c (diff)
Merge branch 'bug14/remove-aidl'
-rw-r--r--src/androidTest/java/com/morlunk/jumble/test/JumbleServiceTest.java11
-rw-r--r--src/main/aidl/com/morlunk/jumble/IJumbleObserver.aidl53
-rw-r--r--src/main/aidl/com/morlunk/jumble/IJumbleService.aidl108
-rw-r--r--src/main/aidl/com/morlunk/jumble/model/IChannel.aidl32
-rw-r--r--src/main/aidl/com/morlunk/jumble/model/IMessage.aidl27
-rw-r--r--src/main/aidl/com/morlunk/jumble/model/IUser.aidl44
-rw-r--r--src/main/aidl/com/morlunk/jumble/model/Server.aidl19
-rw-r--r--src/main/aidl/com/morlunk/jumble/model/TalkState.aidl4
-rw-r--r--src/main/aidl/com/morlunk/jumble/util/JumbleException.aidl3
-rw-r--r--src/main/aidl/com/morlunk/jumble/util/ParcelableByteArray.aidl19
-rw-r--r--src/main/java/com/morlunk/jumble/IJumbleService.java225
-rw-r--r--src/main/java/com/morlunk/jumble/JumbleService.java798
-rw-r--r--src/main/java/com/morlunk/jumble/exception/NotConnectedException.java32
-rw-r--r--src/main/java/com/morlunk/jumble/exception/NotSynchronizedException.java32
-rw-r--r--src/main/java/com/morlunk/jumble/model/Channel.java13
-rw-r--r--src/main/java/com/morlunk/jumble/model/IChannel.java46
-rw-r--r--src/main/java/com/morlunk/jumble/model/IMessage.java36
-rw-r--r--src/main/java/com/morlunk/jumble/model/IUser.java65
-rw-r--r--src/main/java/com/morlunk/jumble/model/Message.java9
-rw-r--r--src/main/java/com/morlunk/jumble/model/User.java21
-rw-r--r--src/main/java/com/morlunk/jumble/net/JumbleConnection.java38
-rw-r--r--src/main/java/com/morlunk/jumble/protocol/ModelHandler.java66
-rw-r--r--src/main/java/com/morlunk/jumble/util/IJumbleObserver.java65
-rw-r--r--src/main/java/com/morlunk/jumble/util/JumbleCallbacks.java186
-rw-r--r--src/main/java/com/morlunk/jumble/util/JumbleObserver.java49
-rw-r--r--src/main/java/com/morlunk/jumble/util/ParcelableByteArray.java67
26 files changed, 1129 insertions, 939 deletions
diff --git a/src/androidTest/java/com/morlunk/jumble/test/JumbleServiceTest.java b/src/androidTest/java/com/morlunk/jumble/test/JumbleServiceTest.java
index e4f0d68..0776335 100644
--- a/src/androidTest/java/com/morlunk/jumble/test/JumbleServiceTest.java
+++ b/src/androidTest/java/com/morlunk/jumble/test/JumbleServiceTest.java
@@ -21,7 +21,6 @@ import android.content.Intent;
import android.os.RemoteException;
import android.test.ServiceTestCase;
-import com.morlunk.jumble.IJumbleService;
import com.morlunk.jumble.JumbleService;
import com.morlunk.jumble.model.Server;
@@ -45,12 +44,10 @@ public class JumbleServiceTest extends ServiceTestCase<JumbleService> {
intent.putExtra(JumbleService.EXTRAS_SERVER, DUMMY_SERVER);
startService(intent);
JumbleService service = getService();
- IJumbleService binder = service.getBinder();
- assertFalse(binder.isReconnecting());
- assertNull(binder.getConnectionError());
- assertEquals(JumbleService.STATE_DISCONNECTED, binder.getConnectionState());
- assertFalse(binder.isTalking());
- assertEquals(DUMMY_SERVER, binder.getConnectedServer());
+ assertFalse(service.isReconnecting());
+ assertNull(service.getConnectionError());
+ assertEquals(JumbleService.ConnectionState.DISCONNECTED, service.getConnectionState());
+ assertEquals(DUMMY_SERVER, service.getConnectedServer());
}
}
diff --git a/src/main/aidl/com/morlunk/jumble/IJumbleObserver.aidl b/src/main/aidl/com/morlunk/jumble/IJumbleObserver.aidl
deleted file mode 100644
index 50e80f3..0000000
--- a/src/main/aidl/com/morlunk/jumble/IJumbleObserver.aidl
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2013 Andrew Comminos
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.morlunk.jumble;
-
-import com.morlunk.jumble.model.IChannel;
-import com.morlunk.jumble.model.IUser;
-import com.morlunk.jumble.model.IMessage;
-import com.morlunk.jumble.util.ParcelableByteArray;
-import com.morlunk.jumble.util.JumbleException;
-
-interface IJumbleObserver {
- // Connection
- void onConnected();
- void onConnecting();
- void onDisconnected(in JumbleException e);
-
- // Authentication
- void onTLSHandshakeFailed(in ParcelableByteArray cert);
-
- // Channel
- void onChannelAdded(in IChannel channel);
- void onChannelStateUpdated(in IChannel channel);
- void onChannelRemoved(in IChannel channel);
- void onChannelPermissionsUpdated(in IChannel channel);
-
- // User
- void onUserConnected(in IUser user);
- void onUserStateUpdated(in IUser user);
- void onUserTalkStateUpdated(in IUser user);
- void onUserJoinedChannel(in IUser user, in IChannel newChannel, in IChannel oldChannel);
- void onUserRemoved(in IUser user, String reason);
- void onPermissionDenied(String reason);
-
- // Logging & Messaging
- void onMessageLogged(in IMessage message);
- void onLogInfo(String message);
- void onLogWarning(String message);
- void onLogError(String message);
-}
diff --git a/src/main/aidl/com/morlunk/jumble/IJumbleService.aidl b/src/main/aidl/com/morlunk/jumble/IJumbleService.aidl
deleted file mode 100644
index ea3efd1..0000000
--- a/src/main/aidl/com/morlunk/jumble/IJumbleService.aidl
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2013 Andrew Comminos
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.morlunk.jumble;
-
-import com.morlunk.jumble.model.IUser;
-import com.morlunk.jumble.model.IChannel;
-import com.morlunk.jumble.model.Server;
-import com.morlunk.jumble.model.IMessage;
-import com.morlunk.jumble.IJumbleObserver;
-import com.morlunk.jumble.util.JumbleException;
-
-interface IJumbleService {
- // Network
- int getConnectionState();
- JumbleException getConnectionError();
- boolean isReconnecting();
- void cancelReconnect();
- void disconnect();
- /**
- * Gets the TCP latency, in nanoseconds.
- */
- long getTCPLatency();
- /**
- * Gets the UDP latency, in nanoseconds.
- */
- long getUDPLatency();
- int getMaxBandwidth();
- int getCurrentBandwidth();
-
- // Server information
- int getServerVersion();
- String getServerRelease();
- String getServerOSName();
- String getServerOSVersion();
-
- // Session and users
- int getSession();
- IUser getSessionUser();
- IChannel getSessionChannel();
- Server getConnectedServer();
- IUser getUser(int id);
- IChannel getChannel(int id);
- IChannel getRootChannel();
- int getPermissions();
-
- // Audio actions and settings
- boolean isTalking();
- void setTalkingState(boolean talking);
- int getTransmitMode();
- int getCodec();
-
- // Bluetooth
- boolean usingBluetoothSco();
- void enableBluetoothSco();
- void disableBluetoothSco();
-
- // Server actions
- void joinChannel(int channel);
- void moveUserToChannel(int session, int channel);
- void createChannel(int parent, String name, String description, int position, boolean temporary);
- void sendAccessTokens(in List tokens);
- //void setTexture(byte[] texture);
- void requestBanList();
- void requestUserList();
- //void requestACL(int channel);
- void requestPermissions(int channel);
- void requestComment(int session);
- void requestAvatar(int session);
- void requestChannelDescription(int channel);
- void registerUser(int session);
- void kickBanUser(int session, String reason, boolean ban);
- IMessage sendUserTextMessage(int session, String message);
- IMessage sendChannelTextMessage(int channel, String message, boolean tree);
- void setUserComment(int session, String comment);
- void setPrioritySpeaker(int session, boolean priority);
- void removeChannel(int channel);
- //void addChannelLink(int channel, int link);
- //void requestChannelPermissions(int channel);
- void setMuteDeafState(int session, boolean mute, boolean deaf);
- void setSelfMuteDeafState(boolean mute, boolean deaf);
- //void announceRecordingState(boolean recording);
-
- // Observation
- void registerObserver(in IJumbleObserver observer);
- void unregisterObserver(in IJumbleObserver observer);
-
- /**
- * Reconfigures the JumbleService with the given extras.
- * These are the same extras you would pass in for a connect call. This "patches" the service
- * only with the new extras specified.
- * @return true if the a reconnect is required for changes to take effect.
- */
- boolean reconfigure(in Bundle extras);
-} \ No newline at end of file
diff --git a/src/main/aidl/com/morlunk/jumble/model/IChannel.aidl b/src/main/aidl/com/morlunk/jumble/model/IChannel.aidl
deleted file mode 100644
index e393f0b..0000000
--- a/src/main/aidl/com/morlunk/jumble/model/IChannel.aidl
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2013 Andrew Comminos
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.morlunk.jumble.model;
-
-interface IChannel {
- int getId();
- int getPosition();
- boolean isTemporary();
- IChannel getParent();
- String getName();
- String getDescription();
- byte[] getDescriptionHash();
- List getUsers();
- List getSubchannels();
- List getLinks();
- int getSubchannelUserCount();
- int getPermissions();
-} \ No newline at end of file
diff --git a/src/main/aidl/com/morlunk/jumble/model/IMessage.aidl b/src/main/aidl/com/morlunk/jumble/model/IMessage.aidl
deleted file mode 100644
index 623a94e..0000000
--- a/src/main/aidl/com/morlunk/jumble/model/IMessage.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2013 Andrew Comminos
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.morlunk.jumble.model;
-
-interface IMessage {
- int getActor();
- String getActorName();
- List getTargetChannels();
- List getTargetTrees();
- List getTargetUsers();
- String getMessage();
- long getReceivedTime();
-} \ No newline at end of file
diff --git a/src/main/aidl/com/morlunk/jumble/model/IUser.aidl b/src/main/aidl/com/morlunk/jumble/model/IUser.aidl
deleted file mode 100644
index aa0f71a..0000000
--- a/src/main/aidl/com/morlunk/jumble/model/IUser.aidl
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2013 Andrew Comminos
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.morlunk.jumble.model;
-
-import com.morlunk.jumble.model.IChannel;
-import com.morlunk.jumble.model.TalkState;
-
-interface IUser {
- int getSession();
- IChannel getChannel();
- int getUserId();
- String getName();
- String getComment();
- byte[] getCommentHash();
- byte[] getTexture();
- byte[] getTextureHash();
- String getHash();
- boolean isMuted();
- boolean isDeafened();
- boolean isSuppressed();
- boolean isSelfMuted();
- boolean isSelfDeafened();
- boolean isPrioritySpeaker();
- boolean isRecording();
- boolean isLocalMuted();
- boolean isLocalIgnored();
- void setLocalMuted(boolean localMuted);
- void setLocalIgnored(boolean localIgnored);
- TalkState getTalkState();
-} \ No newline at end of file
diff --git a/src/main/aidl/com/morlunk/jumble/model/Server.aidl b/src/main/aidl/com/morlunk/jumble/model/Server.aidl
deleted file mode 100644
index d39a553..0000000
--- a/src/main/aidl/com/morlunk/jumble/model/Server.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2013 Andrew Comminos
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.morlunk.jumble.model;
-
-parcelable Server;
diff --git a/src/main/aidl/com/morlunk/jumble/model/TalkState.aidl b/src/main/aidl/com/morlunk/jumble/model/TalkState.aidl
deleted file mode 100644
index 786bc26..0000000
--- a/src/main/aidl/com/morlunk/jumble/model/TalkState.aidl
+++ /dev/null
@@ -1,4 +0,0 @@
-// TalkState.aidl
-package com.morlunk.jumble.model;
-
-parcelable TalkState; \ No newline at end of file
diff --git a/src/main/aidl/com/morlunk/jumble/util/JumbleException.aidl b/src/main/aidl/com/morlunk/jumble/util/JumbleException.aidl
deleted file mode 100644
index d63ffc7..0000000
--- a/src/main/aidl/com/morlunk/jumble/util/JumbleException.aidl
+++ /dev/null
@@ -1,3 +0,0 @@
-package com.morlunk.jumble.util;
-
-parcelable JumbleException;
diff --git a/src/main/aidl/com/morlunk/jumble/util/ParcelableByteArray.aidl b/src/main/aidl/com/morlunk/jumble/util/ParcelableByteArray.aidl
deleted file mode 100644
index 5fb2228..0000000
--- a/src/main/aidl/com/morlunk/jumble/util/ParcelableByteArray.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2013 Andrew Comminos
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.morlunk.jumble.util;
-
-parcelable ParcelableByteArray;
diff --git a/src/main/java/com/morlunk/jumble/IJumbleService.java b/src/main/java/com/morlunk/jumble/IJumbleService.java
new file mode 100644
index 0000000..6e149d0
--- /dev/null
+++ b/src/main/java/com/morlunk/jumble/IJumbleService.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2015 Andrew Comminos <andrew@comminos.com>
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.morlunk.jumble;
+
+import com.morlunk.jumble.model.IChannel;
+import com.morlunk.jumble.model.IUser;
+import com.morlunk.jumble.model.Message;
+import com.morlunk.jumble.model.Server;
+import com.morlunk.jumble.net.JumbleUDPMessageType;
+import com.morlunk.jumble.util.IJumbleObserver;
+import com.morlunk.jumble.util.JumbleException;
+
+import java.util.List;
+
+/**
+ * A public interface for clients to communicate with a {@link JumbleService}.
+ * The long-term goal for this class is to migrate of the complexity out of this class into a
+ * JumbleProtocol class that is owned by a {@link com.morlunk.jumble.net.JumbleConnection}.
+ * <br><br>
+ * Calls are not guaranteed to be thread-safe, so only call the binder from the main thread.
+ * Service state changes related to connection state are only guaranteed to work if isConnected()
+ * is checked to be true.
+ * <br><br>
+ * If not explicitly stated in the method documentation, any call that depends on connection state
+ * will throw IllegalStateException if disconnected or not synchronized.
+ */
+public interface IJumbleService {
+ /**
+ * Returns the current connection state of the service.
+ * @return one of {@link JumbleService.ConnectionState}.
+ */
+ JumbleService.ConnectionState getConnectionState();
+
+ /**
+ * If the {@link JumbleService} disconnected due to an error, returns that error.
+ * @return The error causing disconnection. If the last disconnection was successful or a
+ * connection has yet to be established, returns null.
+ */
+ JumbleException getConnectionError();
+
+ /**
+ * Returns the reconnection state of the {@link JumbleService}.
+ * @return true if the service will attempt to automatically reconnect in the future.
+ */
+ boolean isReconnecting();
+
+ /**
+ * Cancels any future reconnection attempts. Does nothing if reconnection is not in progress.
+ */
+ void cancelReconnect();
+
+ /**
+ * @return the latency in milliseconds for the TCP connection.
+ * @throws IllegalStateException if not connected.
+ */
+ long getTCPLatency();
+
+ /**
+ * @return the latency in milliseconds for the UDP connection.
+ * @throws IllegalStateException if not connected.
+ */
+ long getUDPLatency();
+
+ /**
+ * @return the maximum bandwidth in bps for audio allowed by the server, or -1 if not set.
+ * @throws IllegalStateException if not synchronized.
+ */
+ int getMaxBandwidth();
+
+ /**
+ * @return the current bandwidth in bps for audio sent to the server, or a negative integer
+ * if unknown (prior to connection or after disconnection).
+ * @throws IllegalStateException if not synchronized.
+ */
+ int getCurrentBandwidth();
+
+ /**
+ * Returns the protocol version returned by the server in the format 0xAABBCC, where AA
+ * indicates the major version, BB indicates the minor version, and CC indicates the patch
+ * version. This is the same formatting used by the Mumble protocol in big-endian format.
+ * @return the current bandwidth in bps for audio sent to the server, or a negative integer
+ * if unknown (prior to connection or after disconnection).
+ * @throws IllegalStateException if not synchronized.
+ */
+ int getServerVersion();
+
+ /**
+ * @return a user-readable string with the server's Mumble release info.
+ * @throws IllegalStateException if not synchronized.
+ */
+ String getServerRelease();
+
+ /**
+ * @return a user-readable string with the server's OS name.
+ * @throws IllegalStateException if not connected.
+ */
+ String getServerOSName();
+
+ /**
+ * @return a user-readable string with the server's OS version.
+ * @throws IllegalStateException if not synchronized.
+ */
+ String getServerOSVersion();
+
+ /**
+ * Returns the current user's session. Set during server synchronization.
+ * @return an integer identifying the current user's connection.
+ * @throws IllegalStateException if not synchronized.
+ */
+ int getSession();
+
+ /**
+ * Returns the current user. Set during server synchronization.
+ * @return the {@link IUser} representing the current user.
+ * @throws IllegalStateException if not synchronized.
+ */
+ IUser getSessionUser();
+
+ /**
+ * Returns the user's current channel.
+ * @return the {@link IChannel} representing the user's current channel.
+ * @throws IllegalStateException if not synchronized.
+ */
+ IChannel getSessionChannel();
+
+ /**
+ * @return the server that Jumble is currently connected to (or attempted connection to).
+ */
+ Server getConnectedServer();
+
+ /**
+ * Retrieves the user with the given session ID.
+ * @param session An integer ID identifying a user's session. See {@link IUser#getSession()}.
+ * @return A user with the given session, or null if not found.
+ * @throws IllegalStateException if not synchronized.
+ */
+ IUser getUser(int session);
+
+ /**
+ * Retrieves the channel with the given ID.
+ * @param id An integer ID identifying a channel. See {@link IChannel#getId()}.
+ * @return A channel with the given session, or null if not found.
+ * @throws IllegalStateException if not synchronized.
+ */
+ IChannel getChannel(int id);
+
+ /**
+ * @return the root channel of the server.
+ * @throws IllegalStateException if not synchronized.
+ */
+ IChannel getRootChannel();
+
+ int getPermissions();
+
+ int getTransmitMode();
+
+ JumbleUDPMessageType getCodec();
+
+ boolean usingBluetoothSco();
+
+ void enableBluetoothSco();
+
+ void disableBluetoothSco();
+
+ boolean isTalking();
+
+ void setTalkingState(boolean talking);
+
+ void joinChannel(int channel);
+
+ void moveUserToChannel(int session, int channel);
+
+ void createChannel(int parent, String name, String description, int position, boolean temporary);
+
+ void sendAccessTokens(List<String> tokens);
+
+ void requestBanList();
+
+ void requestUserList();
+
+ void requestPermissions(int channel);
+
+ void requestComment(int session);
+
+ void requestAvatar(int session);
+
+ void requestChannelDescription(int channel);
+
+ void registerUser(int session);
+
+ void kickBanUser(int session, String reason, boolean ban);
+
+ Message sendUserTextMessage(int session, String message);
+
+ Message sendChannelTextMessage(int channel, String message, boolean tree);
+
+ void setUserComment(int session, String comment);
+
+ void setPrioritySpeaker(int session, boolean priority);
+
+ void removeChannel(int channel);
+
+ void setMuteDeafState(int session, boolean mute, boolean deaf);
+
+ void setSelfMuteDeafState(boolean mute, boolean deaf);
+
+ void registerObserver(IJumbleObserver observer);
+
+ void unregisterObserver(IJumbleObserver observer);
+}
diff --git a/src/main/java/com/morlunk/jumble/JumbleService.java b/src/main/java/com/morlunk/jumble/JumbleService.java
index 63e4b3c..e9fd0c1 100644
--- a/src/main/java/com/morlunk/jumble/JumbleService.java
+++ b/src/main/java/com/morlunk/jumble/JumbleService.java
@@ -25,17 +25,19 @@ import android.content.IntentFilter;
import android.media.AudioManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
+import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.PowerManager;
-import android.os.RemoteException;
import android.util.Log;
import com.morlunk.jumble.audio.AudioOutput;
import com.morlunk.jumble.audio.BluetoothScoReceiver;
import com.morlunk.jumble.exception.AudioException;
+import com.morlunk.jumble.exception.NotConnectedException;
+import com.morlunk.jumble.exception.NotSynchronizedException;
import com.morlunk.jumble.model.Channel;
import com.morlunk.jumble.model.IChannel;
import com.morlunk.jumble.model.IUser;
@@ -44,6 +46,8 @@ import com.morlunk.jumble.model.Server;
import com.morlunk.jumble.model.TalkState;
import com.morlunk.jumble.model.User;
import com.morlunk.jumble.net.JumbleConnection;
+import com.morlunk.jumble.net.JumbleUDPMessageType;
+import com.morlunk.jumble.util.IJumbleObserver;
import com.morlunk.jumble.util.JumbleException;
import com.morlunk.jumble.net.JumbleTCPMessageType;
import com.morlunk.jumble.protobuf.Mumble;
@@ -51,15 +55,13 @@ import com.morlunk.jumble.protocol.AudioHandler;
import com.morlunk.jumble.protocol.ModelHandler;
import com.morlunk.jumble.util.JumbleCallbacks;
import com.morlunk.jumble.util.JumbleLogger;
-import com.morlunk.jumble.util.ParcelableByteArray;
import java.security.Security;
-import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
-public class JumbleService extends Service implements JumbleConnection.JumbleConnectionListener, JumbleLogger, BluetoothScoReceiver.Listener {
+public class JumbleService extends Service implements IJumbleService, JumbleConnection.JumbleConnectionListener, JumbleLogger, BluetoothScoReceiver.Listener {
static {
// Use Spongy Castle for crypto implementation so we can create and manage PKCS #12 (.p12) certificates.
@@ -67,27 +69,6 @@ public class JumbleService extends Service implements JumbleConnection.JumbleCon
}
/**
- * The default state of Jumble, before connection to a server and after graceful/expected
- * disconnection from a server.
- */
- public static final int STATE_DISCONNECTED = 0;
- /**
- * A connection to the server is currently in progress.
- */
- public static final int STATE_CONNECTING = 1;
- /**
- * Jumble has received all data necessary for normal protocol communication with the server.
- */
- public static final int STATE_CONNECTED = 2;
- /**
- * The connection was lost due to either a kick/ban or socket I/O error.
- * Jumble can be reconnecting in this state.
- * @see IJumbleService#isReconnecting()
- * @see IJumbleService#cancelReconnect()
- */
- public static final int STATE_CONNECTION_LOST = 3;
-
- /**
* An action to immediately connect to a given Mumble server.
* Requires that {@link #EXTRAS_SERVER} is provided.
*/
@@ -146,10 +127,9 @@ public class JumbleService extends Service implements JumbleConnection.JumbleCon
private PowerManager.WakeLock mWakeLock;
private Handler mHandler;
private JumbleCallbacks mCallbacks;
- private IJumbleService.Stub mBinder = new JumbleBinder();
private JumbleConnection mConnection;
- private int mConnectionState;
+ private ConnectionState mConnectionState;
private ModelHandler mModelHandler;
private AudioHandler mAudioHandler;
private BluetoothScoReceiver mBluetoothReceiver;
@@ -189,14 +169,16 @@ public class JumbleService extends Service implements JumbleConnection.JumbleCon
mHandler.post(new Runnable() {
@Override
public void run() {
- if(!isConnected()) return;
- final User currentUser = mModelHandler.getUser(mConnection.getSession());
- if(currentUser == null) return;
-
- currentUser.setTalkState(state);
try {
+ if (!isSynchronized())
+ throw new NotSynchronizedException();
+
+ final User currentUser = mModelHandler.getUser(mConnection.getSession());
+ if (currentUser == null) return;
+
+ currentUser.setTalkState(state);
mCallbacks.onUserTalkStateUpdated(currentUser);
- } catch (RemoteException e) {
+ } catch (NotSynchronizedException e) {
e.printStackTrace();
}
}
@@ -207,11 +189,7 @@ public class JumbleService extends Service implements JumbleConnection.JumbleCon
private AudioOutput.AudioOutputListener mAudioOutputListener = new AudioOutput.AudioOutputListener() {
@Override
public void onUserTalkStateUpdated(final User user) {
- try {
- mCallbacks.onUserTalkStateUpdated(user);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
+ mCallbacks.onUserTalkStateUpdated(user);
}
@Override
@@ -234,7 +212,7 @@ public class JumbleService extends Service implements JumbleConnection.JumbleCon
if (ACTION_CONNECT.equals(intent.getAction())) {
if (extras == null || !extras.containsKey(EXTRAS_SERVER)) {
- // Ensure that we have been provided all required attributes.
+ // Ensure that we have been provided all required attributes.```
throw new RuntimeException(ACTION_CONNECT + " requires a server provided in extras.");
}
connect();
@@ -256,7 +234,7 @@ public class JumbleService extends Service implements JumbleConnection.JumbleCon
.setLogger(this)
.setEncodeListener(mAudioInputListener)
.setTalkingListener(mAudioOutputListener);
- mConnectionState = STATE_DISCONNECTED;
+ mConnectionState = ConnectionState.DISCONNECTED;
mBluetoothReceiver = new BluetoothScoReceiver(this, this);
registerReceiver(mBluetoothReceiver, new IntentFilter(AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED));
}
@@ -264,22 +242,17 @@ public class JumbleService extends Service implements JumbleConnection.JumbleCon
@Override
public void onDestroy() {
unregisterReceiver(mBluetoothReceiver);
- mCallbacks.kill();
super.onDestroy();
}
public IBinder onBind(Intent intent) {
- return mBinder;
- }
-
- public IJumbleService getBinder() {
- return mBinder;
+ return new JumbleBinder(this);
}
- public void connect() {
+ protected void connect() {
try {
setReconnecting(false);
- mConnectionState = STATE_DISCONNECTED;
+ mConnectionState = ConnectionState.DISCONNECTED;
mConnection = new JumbleConnection(this);
mConnection.setForceTCP(mForceTcp);
@@ -291,22 +264,14 @@ public class JumbleService extends Service implements JumbleConnection.JumbleCon
mLocalMuteHistory, mLocalIgnoreHistory);
mConnection.addTCPMessageHandlers(mModelHandler);
- mConnectionState = STATE_CONNECTING;
+ mConnectionState = ConnectionState.CONNECTING;
- try {
- mCallbacks.onConnecting();
- } catch (RemoteException e) {
- e.printStackTrace();
- }
+ mCallbacks.onConnecting();
mConnection.connect(mServer.getHost(), mServer.getPort());
} catch (JumbleException e) {
e.printStackTrace();
- try {
- mCallbacks.onDisconnected(e);
- } catch (RemoteException e1) {
- e1.printStackTrace();
- }
+ mCallbacks.onDisconnected(e);
}
}
@@ -314,10 +279,18 @@ public class JumbleService extends Service implements JumbleConnection.JumbleCon
mConnection.disconnect();
}
- public boolean isConnected() {
+ public boolean isConnectionEstablished() {
return mConnection != null && mConnection.isConnected();
}
+ /**
+ * @return true if Jumble has received the ServerSync message, indicating synchronization with
+ * the server's model and settings. This is the main state of the service.
+ */
+ public boolean isSynchronized() {
+ return mConnection != null && mConnection.isSynchronized();
+ }
+
@Override
public void onConnectionEstablished() {
// Send version information and authenticate.
@@ -342,7 +315,7 @@ public class JumbleService extends Service implements JumbleConnection.JumbleCon
@Override
public void onConnectionSynchronized() {
- mConnectionState = STATE_CONNECTED;
+ mConnectionState = ConnectionState.CONNECTED;
Log.v(Constants.TAG, "Connected");
mWakeLock.acquire();
@@ -356,25 +329,16 @@ public class JumbleService extends Service implements JumbleConnection.JumbleCon
} catch (AudioException e) {
e.printStackTrace();
onConnectionWarning(e.getMessage());
+ } catch (NotSynchronizedException e) {
+ throw new RuntimeException("Connection should be synchronized in callback for synchronization!", e);
}
- try {
- mCallbacks.onConnected();
- } catch (RemoteException e) {
- e.printStackTrace();
- }
+ mCallbacks.onConnected();
}
@Override
public void onConnectionHandshakeFailed(X509Certificate[] chain) {
- try {
- final ParcelableByteArray encodedCert = new ParcelableByteArray(chain[0].getEncoded());
- mCallbacks.onTLSHandshakeFailed(encodedCert);
- } catch (CertificateEncodingException e) {
- e.printStackTrace();
- } catch (RemoteException e) {
- e.printStackTrace();
- }
+ mCallbacks.onTLSHandshakeFailed(chain);
}
@Override
@@ -382,13 +346,13 @@ public class JumbleService extends Service implements JumbleConnection.JumbleCon
if (e != null) {
Log.e(Constants.TAG, "Error: " + e.getMessage() +
" (reason: " + e.getReason().name() + ")");
- mConnectionState = STATE_CONNECTION_LOST;
+ mConnectionState = ConnectionState.CONNECTION_LOST;
setReconnecting(mAutoReconnect
&& e.getReason() == JumbleException.JumbleDisconnectReason.CONNECTION_ERROR);
} else {
Log.v(Constants.TAG, "Disconnected");
- mConnectionState = STATE_DISCONNECTED;
+ mConnectionState = ConnectionState.DISCONNECTED;
}
if(mWakeLock.isHeld()) {
@@ -405,11 +369,7 @@ public class JumbleService extends Service implements JumbleConnection.JumbleCon
// Halt SCO connection on shutdown.
mBluetoothReceiver.stopBluetoothSco();
- try {
- mCallbacks.onDisconnected(e);
- } catch (RemoteException re) {
- re.printStackTrace();
- }
+ mCallbacks.onDisconnected(e);
}
@Override
@@ -421,32 +381,23 @@ public class JumbleService extends Service implements JumbleConnection.JumbleCon
public void logInfo(String message) {
if (mConnection == null || !mConnection.isSynchronized())
return; // don't log info prior to synchronization
- try {
- mCallbacks.onLogInfo(message);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
+ mCallbacks.onLogInfo(message);
}
@Override
public void logWarning(String message) {
- try {
- mCallbacks.onLogWarning(message);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
+ mCallbacks.onLogWarning(message);
}
@Override
public void logError(String message) {
- try {
- mCallbacks.onLogError(message);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
+ mCallbacks.onLogError(message);
}
- private void setReconnecting(boolean reconnecting) {
+ public void setReconnecting(boolean reconnecting) {
+ if (mReconnecting == reconnecting)
+ return;
+
mReconnecting = reconnecting;
if (reconnecting) {
ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
@@ -486,7 +437,7 @@ public class JumbleService extends Service implements JumbleConnection.JumbleCon
* be known.
*/
private void createAudioHandler() throws AudioException {
- if (BuildConfig.DEBUG && mConnectionState != STATE_CONNECTED) {
+ if (BuildConfig.DEBUG && mConnectionState != ConnectionState.CONNECTED) {
throw new AssertionError("Attempted to instantiate audio handler when not connected!");
}
@@ -496,11 +447,15 @@ public class JumbleService extends Service implements JumbleConnection.JumbleCon
mAudioHandler.shutdown();
}
- mAudioHandler = mAudioBuilder.initialize(
- mModelHandler.getUser(mConnection.getSession()),
- mConnection.getMaxBandwidth(), mConnection.getCodec());
- mConnection.addTCPMessageHandlers(mAudioHandler);
- mConnection.addUDPMessageHandlers(mAudioHandler);
+ try {
+ mAudioHandler = mAudioBuilder.initialize(
+ mModelHandler.getUser(mConnection.getSession()),
+ mConnection.getMaxBandwidth(), mConnection.getCodec());
+ mConnection.addTCPMessageHandlers(mAudioHandler);
+ mConnection.addUDPMessageHandlers(mAudioHandler);
+ } catch (NotSynchronizedException e) {
+ throw new RuntimeException("Attempted to create audio handler when not synchronized!");
+ }
}
/**
@@ -510,7 +465,7 @@ public class JumbleService extends Service implements JumbleConnection.JumbleCon
* @return true if a reconnect is required for changes to take effect.
* @see com.morlunk.jumble.JumbleService
*/
- private boolean configureExtras(Bundle extras) throws AudioException {
+ public boolean configureExtras(Bundle extras) throws AudioException {
boolean reconnectNeeded = false;
if (extras.containsKey(EXTRAS_SERVER)) {
mServer = extras.getParcelable(EXTRAS_SERVER);
@@ -638,342 +593,495 @@ public class JumbleService extends Service implements JumbleConnection.JumbleCon
}
}
- public class JumbleBinder extends IJumbleService.Stub {
- @Override
- public int getConnectionState() throws RemoteException {
- return mConnectionState;
- }
+ /**
+ * Exposes the current connection. The current connection is set once an attempt to connect to
+ * a server is made, and remains set until a subsequent connection. It remains available
+ * after disconnection to provide information regarding the terminated connection.
+ * @return The active {@link JumbleConnection}.
+ */
+ public JumbleConnection getConnection() {
+ return mConnection;
+ }
- @Override
- public JumbleException getConnectionError() throws RemoteException {
- return mConnection != null ? mConnection.getError() : null;
- }
+ /**
+ * Returnes the current {@link AudioHandler}. An AudioHandler is instantiated upon connection
+ * to a server, and destroyed upon disconnection.
+ * @return the active AudioHandler, or null if there is no active connection.
+ */
+ private AudioHandler getAudioHandler() throws NotSynchronizedException {
+ if (!isSynchronized())
+ throw new NotSynchronizedException();
+ if (mAudioHandler == null && mConnectionState == ConnectionState.CONNECTED)
+ throw new RuntimeException("Audio handler should always be instantiated while connected!");
+ return mAudioHandler;
+ }
- @Override
- public boolean isReconnecting() throws RemoteException {
- return mReconnecting;
- }
+ /**
+ * Returns the current {@link ModelHandler}, containing the channel tree. A model handler is
+ * valid for the lifetime of a connection.
+ * @return the active ModelHandler, or null if there is no active connection.
+ */
+ private ModelHandler getModelHandler() throws NotSynchronizedException {
+ if (!isSynchronized())
+ throw new NotSynchronizedException();
+ if (mModelHandler == null && mConnectionState == ConnectionState.CONNECTED)
+ throw new RuntimeException("Model handler should always be instantiated while connected!");
+ return mModelHandler;
+ }
- @Override
- public void cancelReconnect() throws RemoteException {
- setReconnecting(false);
- }
+ /**
+ * Returns the bluetooth service provider, established after synchronization.
+ * @return The {@link BluetoothScoReceiver} attached to this service.
+ */
+ private BluetoothScoReceiver getBluetoothReceiver() throws NotSynchronizedException {
+ if (!isSynchronized())
+ throw new NotSynchronizedException();
+ return mBluetoothReceiver;
+ }
- @Override
- public void disconnect() throws RemoteException {
- JumbleService.this.disconnect();
- }
+ @Override
+ public JumbleService.ConnectionState getConnectionState() {
+ return mConnectionState;
+ }
- @Override
- public long getTCPLatency() throws RemoteException {
- return mConnection.getTCPLatency();
- }
+ @Override
+ public JumbleException getConnectionError() {
+ JumbleConnection connection = getConnection();
+ return connection != null ? connection.getError() : null;
+ }
- @Override
- public long getUDPLatency() throws RemoteException {
- return mConnection.getUDPLatency();
- }
+ @Override
+ public boolean isReconnecting() {
+ return mReconnecting;
+ }
- @Override
- public int getMaxBandwidth() throws RemoteException {
- return mConnection.getMaxBandwidth();
- }
+ @Override
+ public void cancelReconnect() {
+ setReconnecting(false);
+ }
- @Override
- public int getCurrentBandwidth() throws RemoteException {
- return mAudioHandler.getCurrentBandwidth();
+ @Override
+ public long getTCPLatency() {
+ try {
+ return getConnection().getTCPLatency();
+ } catch (NotConnectedException e) {
+ throw new IllegalStateException(e);
}
+ }
- @Override
- public int getServerVersion() throws RemoteException {
- return mConnection.getServerVersion();
+ @Override
+ public long getUDPLatency() {
+ try {
+ return getConnection().getUDPLatency();
+ } catch (NotConnectedException e) {
+ throw new IllegalStateException(e);
}
+ }
- @Override
- public String getServerRelease() throws RemoteException {
- return mConnection.getServerRelease();
+ @Override
+ public int getMaxBandwidth() {
+ try {
+ return getConnection().getMaxBandwidth();
+ } catch (NotSynchronizedException e) {
+ throw new IllegalStateException(e);
}
+ }
- @Override
- public String getServerOSName() throws RemoteException {
- return mConnection.getServerOSName();
+ @Override
+ public int getCurrentBandwidth() {
+ try {
+ return getAudioHandler().getCurrentBandwidth();
+ } catch (NotSynchronizedException e) {
+ throw new IllegalStateException(e);
}
+ }
- @Override
- public String getServerOSVersion() throws RemoteException {
- return mConnection.getServerOSVersion();
+ @Override
+ public int getServerVersion() {
+ try {
+ return getConnection().getServerVersion();
+ } catch (NotSynchronizedException e) {
+ throw new IllegalStateException(e);
}
+ }
- @Override
- public int getSession() throws RemoteException {
- return mConnection != null ? mConnection.getSession() : -1;
+ @Override
+ public String getServerRelease() {
+ try {
+ return getConnection().getServerRelease();
+ } catch (NotSynchronizedException e) {
+ throw new IllegalStateException(e);
}
+ }
- @Override
- public IUser getSessionUser() throws RemoteException {
- return mModelHandler != null ? mModelHandler.getUser(getSession()) : null;
+ @Override
+ public String getServerOSName() {
+ try {
+ return getConnection().getServerOSName();
+ } catch (NotSynchronizedException e) {
+ throw new IllegalStateException(e);
}
+ }
- @Override
- public IChannel getSessionChannel() throws RemoteException {
- IUser user = getSessionUser();
- if (user != null) {
- return user.getChannel();
- }
- return null;
+ @Override
+ public String getServerOSVersion() {
+ try {
+ return getConnection().getServerOSVersion();
+ } catch (NotSynchronizedException e) {
+ throw new IllegalStateException(e);
}
+ }
- @Override
- public Server getConnectedServer() throws RemoteException {
- return mServer;
+ @Override
+ public int getSession() {
+ try {
+ return getConnection().getSession();
+ } catch (NotSynchronizedException e) {
+ throw new IllegalStateException(e);
}
+ }
- @Override
- public IUser getUser(int id) throws RemoteException {
- if (mModelHandler != null)
- return mModelHandler.getUser(id);
- return null;
+ @Override
+ public IUser getSessionUser() {
+ try {
+ return getModelHandler().getUser(getSession());
+ } catch (NotSynchronizedException e) {
+ throw new IllegalStateException(e);
}
+ }
- @Override
- public IChannel getChannel(int id) throws RemoteException {
- if (mModelHandler != null)
- return mModelHandler.getChannel(id);
- return null;
+ @Override
+ public IChannel getSessionChannel() {
+ IUser user = getSessionUser();
+ if (user != null)
+ return user.getChannel();
+ throw new IllegalStateException("Session user should be set post-synchronization!");
+ }
+
+ @Override
+ public Server getConnectedServer() {
+ return mServer;
+ }
+
+ @Override
+ public IUser getUser(int session) {
+ try {
+ return getModelHandler().getUser(session);
+ } catch (NotSynchronizedException e) {
+ throw new IllegalStateException(e);
}
+ }
- @Override
- public IChannel getRootChannel() throws RemoteException {
- return getChannel(0);
+ @Override
+ public IChannel getChannel(int id) {
+ try {
+ return getModelHandler().getChannel(id);
+ } catch (NotSynchronizedException e) {
+ throw new IllegalStateException(e);
}
+ }
- @Override
- public int getPermissions() throws RemoteException {
- return mModelHandler != null ? mModelHandler.getPermissions() : 0;
+ @Override
+ public IChannel getRootChannel() {
+ return getChannel(0);
+ }
+
+ @Override
+ public int getPermissions() {
+ try {
+ return getModelHandler().getPermissions();
+ } catch (NotSynchronizedException e) {
+ throw new IllegalStateException(e);
}
+ }
- @Override
- public int getTransmitMode() throws RemoteException {
- return mAudioHandler.getTransmitMode();
+ @Override
+ public int getTransmitMode() {
+ try {
+ return getAudioHandler().getTransmitMode();
+ } catch (NotSynchronizedException e) {
+ throw new IllegalStateException(e);
}
+ }
- @Override
- public int getCodec() throws RemoteException {
- return mConnection.getCodec().ordinal(); // FIXME: ordinal is bad, make enum method
+ @Override
+ public JumbleUDPMessageType getCodec() {
+ try {
+ return getConnection().getCodec();
+ } catch (NotSynchronizedException e) {
+ throw new IllegalStateException(e);
}
+ }
- @Override
- public boolean usingBluetoothSco() throws RemoteException {
- return mBluetoothReceiver.isBluetoothScoOn();
+ @Override
+ public boolean usingBluetoothSco() {
+ try {
+ return getBluetoothReceiver().isBluetoothScoOn();
+ } catch (NotSynchronizedException e) {
+ throw new IllegalStateException(e);
}
+ }
- @Override
- public void enableBluetoothSco() throws RemoteException {
- mBluetoothReceiver.startBluetoothSco();
+ @Override
+ public void enableBluetoothSco() {
+ try {
+ getBluetoothReceiver().startBluetoothSco();
+ } catch (NotSynchronizedException e) {
+ throw new IllegalStateException(e);
}
+ }
- @Override
- public void disableBluetoothSco() throws RemoteException {
- mBluetoothReceiver.stopBluetoothSco();
+ @Override
+ public void disableBluetoothSco() {
+ try {
+ getBluetoothReceiver().stopBluetoothSco();
+ } catch (NotSynchronizedException e) {
+ throw new IllegalStateException(e);
}
+ }
- @Override
- public boolean isTalking() throws RemoteException {
- return mAudioHandler != null && mAudioHandler.isRecording();
+ @Override
+ public boolean isTalking() {
+ try {
+ return getAudioHandler().isRecording();
+ } catch (NotSynchronizedException e) {
+ throw new IllegalStateException(e);
}
+ }
- @Override
- public void setTalkingState(boolean talking) throws RemoteException {
- if(getSessionUser() != null &&
- (getSessionUser().isSelfMuted() || getSessionUser().isMuted())) {
- return;
- }
+ @Override
+ public void setTalkingState(boolean talking) {
+ if (getSessionUser().isSelfMuted() || getSessionUser().isMuted())
+ return;
- if (mAudioHandler.getTransmitMode() != Constants.TRANSMIT_PUSH_TO_TALK) {
+ try {
+ if (getAudioHandler().getTransmitMode() != Constants.TRANSMIT_PUSH_TO_TALK) {
Log.w(Constants.TAG, "Attempted to set talking state when not using PTT");
return;
}
try {
- mAudioHandler.setTalking(talking);
+ getAudioHandler().setTalking(talking);
} catch (AudioException e) {
logError(e.getMessage());
}
+ } catch (NotSynchronizedException e) {
+ throw new IllegalStateException(e);
}
+ }
- @Override
- public void joinChannel(int channel) throws RemoteException {
- moveUserToChannel(getSession(), channel);
- }
+ @Override
+ public void joinChannel(int channel) {
+ moveUserToChannel(getSession(), channel);
+ }
- @Override
- public void moveUserToChannel(int session, int channel) throws RemoteException {
- Mumble.UserState.Builder usb = Mumble.UserState.newBuilder();
- usb.setSession(session);
- usb.setChannelId(channel);
- mConnection.sendTCPMessage(usb.build(), JumbleTCPMessageType.UserState);
- }
+ @Override
+ public void moveUserToChannel(int session, int channel) {
+ Mumble.UserState.Builder usb = Mumble.UserState.newBuilder();
+ usb.setSession(session);
+ usb.setChannelId(channel);
+ getConnection().sendTCPMessage(usb.build(), JumbleTCPMessageType.UserState);
+ }
- @Override
- public void createChannel(int parent, String name, String description, int position, boolean temporary) throws RemoteException {
- Mumble.ChannelState.Builder csb = Mumble.ChannelState.newBuilder();
- csb.setParent(parent);
- csb.setName(name);
- csb.setDescription(description);
- csb.setPosition(position);
- csb.setTemporary(temporary);
- mConnection.sendTCPMessage(csb.build(), JumbleTCPMessageType.ChannelState);
- }
+ @Override
+ public void createChannel(int parent, String name, String description, int position, boolean temporary) {
+ Mumble.ChannelState.Builder csb = Mumble.ChannelState.newBuilder();
+ csb.setParent(parent);
+ csb.setName(name);
+ csb.setDescription(description);
+ csb.setPosition(position);
+ csb.setTemporary(temporary);
+ getConnection().sendTCPMessage(csb.build(), JumbleTCPMessageType.ChannelState);
+ }
- @Override
- public void sendAccessTokens(List tokens) throws RemoteException {
- mConnection.sendAccessTokens(tokens);
- }
+ @Override
+ public void sendAccessTokens(final List<String> tokens) {
+ getConnection().sendAccessTokens(tokens);
+ }
- @Override
- public void requestBanList() throws RemoteException {
- throw new UnsupportedOperationException("Not yet implemented"); // TODO
- }
+ @Override
+ public void requestBanList() {
+ throw new UnsupportedOperationException("Not yet implemented"); // TODO
+ }
- @Override
- public void requestUserList() throws RemoteException {
- throw new UnsupportedOperationException("Not yet implemented"); // TODO
- }
+ @Override
+ public void requestUserList() {
+ throw new UnsupportedOperationException("Not yet implemented"); // TODO
+ }
- @Override
- public void requestPermissions(int channel) throws RemoteException {
- Mumble.PermissionQuery.Builder pqb = Mumble.PermissionQuery.newBuilder();
- pqb.setChannelId(channel);
- mConnection.sendTCPMessage(pqb.build(), JumbleTCPMessageType.PermissionQuery);
- }
+ @Override
+ public void requestPermissions(int channel) {
+ Mumble.PermissionQuery.Builder pqb = Mumble.PermissionQuery.newBuilder();
+ pqb.setChannelId(channel);
+ getConnection().sendTCPMessage(pqb.build(), JumbleTCPMessageType.PermissionQuery);
+ }
- @Override
- public void requestComment(int session) throws RemoteException {
- Mumble.RequestBlob.Builder rbb = Mumble.RequestBlob.newBuilder();
- rbb.addSessionComment(session);
- mConnection.sendTCPMessage(rbb.build(), JumbleTCPMessageType.RequestBlob);
- }
+ @Override
+ public void requestComment(int session) {
+ Mumble.RequestBlob.Builder rbb = Mumble.RequestBlob.newBuilder();
+ rbb.addSessionComment(session);
+ getConnection().sendTCPMessage(rbb.build(), JumbleTCPMessageType.RequestBlob);
+ }
- @Override
- public void requestAvatar(int session) throws RemoteException {
- Mumble.RequestBlob.Builder rbb = Mumble.RequestBlob.newBuilder();
- rbb.addSessionTexture(session);
- mConnection.sendTCPMessage(rbb.build(), JumbleTCPMessageType.RequestBlob);
- }
+ @Override
+ public void requestAvatar(int session) {
+ Mumble.RequestBlob.Builder rbb = Mumble.RequestBlob.newBuilder();
+ rbb.addSessionTexture(session);
+ getConnection().sendTCPMessage(rbb.build(), JumbleTCPMessageType.RequestBlob);
+ }
- @Override
- public void requestChannelDescription(int channel) throws RemoteException {
- Mumble.RequestBlob.Builder rbb = Mumble.RequestBlob.newBuilder();
- rbb.addChannelDescription(channel);
- mConnection.sendTCPMessage(rbb.build(), JumbleTCPMessageType.RequestBlob);
- }
+ @Override
+ public void requestChannelDescription(int channel) {
+ Mumble.RequestBlob.Builder rbb = Mumble.RequestBlob.newBuilder();
+ rbb.addChannelDescription(channel);
+ getConnection().sendTCPMessage(rbb.build(), JumbleTCPMessageType.RequestBlob);
+ }
- @Override
- public void registerUser(int session) throws RemoteException {
- Mumble.UserState.Builder usb = Mumble.UserState.newBuilder();
- usb.setSession(session);
- usb.setUserId(0);
- mConnection.sendTCPMessage(usb.build(), JumbleTCPMessageType.UserState);
- }
+ @Override
+ public void registerUser(int session) {
+ Mumble.UserState.Builder usb = Mumble.UserState.newBuilder();
+ usb.setSession(session);
+ usb.setUserId(0);
+ getConnection().sendTCPMessage(usb.build(), JumbleTCPMessageType.UserState);
+ }
- @Override
- public void kickBanUser(int session, String reason, boolean ban) throws RemoteException {
- Mumble.UserRemove.Builder urb = Mumble.UserRemove.newBuilder();
- urb.setSession(session);
- urb.setReason(reason);
- urb.setBan(ban);
- mConnection.sendTCPMessage(urb.build(), JumbleTCPMessageType.UserRemove);
- }
+ @Override
+ public void kickBanUser(int session, String reason, boolean ban) {
+ Mumble.UserRemove.Builder urb = Mumble.UserRemove.newBuilder();
+ urb.setSession(session);
+ urb.setReason(reason);
+ urb.setBan(ban);
+ getConnection().sendTCPMessage(urb.build(), JumbleTCPMessageType.UserRemove);
+ }
+
+ @Override
+ public Message sendUserTextMessage(int session, String message) {
+ try {
+ if (!isSynchronized())
+ throw new NotSynchronizedException();
- @Override
- public Message sendUserTextMessage(int session, String message) throws RemoteException {
Mumble.TextMessage.Builder tmb = Mumble.TextMessage.newBuilder();
tmb.addSession(session);
tmb.setMessage(message);
- mConnection.sendTCPMessage(tmb.build(), JumbleTCPMessageType.TextMessage);
+ getConnection().sendTCPMessage(tmb.build(), JumbleTCPMessageType.TextMessage);
- User self = mModelHandler.getUser(getSession());
- User user = mModelHandler.getUser(session);
+ User self = getModelHandler().getUser(getSession());
+ User user = getModelHandler().getUser(session);
List<User> users = new ArrayList<User>(1);
users.add(user);
return new Message(getSession(), self.getName(), new ArrayList<Channel>(0), new ArrayList<Channel>(0), users, message);
+ } catch (NotSynchronizedException e) {
+ throw new IllegalStateException(e);
}
+ }
+
+ @Override
+ public Message sendChannelTextMessage(int channel, String message, boolean tree) {
+ try {
+ if (!isSynchronized())
+ throw new NotSynchronizedException();
- @Override
- public Message sendChannelTextMessage(int channel, String message, boolean tree) throws RemoteException {
Mumble.TextMessage.Builder tmb = Mumble.TextMessage.newBuilder();
- if(tree) tmb.addTreeId(channel);
+ if (tree) tmb.addTreeId(channel);
else tmb.addChannelId(channel);
tmb.setMessage(message);
- mConnection.sendTCPMessage(tmb.build(), JumbleTCPMessageType.TextMessage);
+ getConnection().sendTCPMessage(tmb.build(), JumbleTCPMessageType.TextMessage);
- User self = mModelHandler.getUser(getSession());
- Channel targetChannel = mModelHandler.getChannel(channel);
+ User self = getModelHandler().getUser(getSession());
+ Channel targetChannel = getModelHandler().getChannel(channel);
List<Channel> targetChannels = new ArrayList<Channel>();
targetChannels.add(targetChannel);
return new Message(getSession(), self.getName(), targetChannels, tree ? targetChannels : new ArrayList<Channel>(0), new ArrayList<User>(0), message);
+ } catch (NotSynchronizedException e) {
+ throw new IllegalStateException(e);
}
+ }
- @Override
- public void setUserComment(int session, String comment) throws RemoteException {
- Mumble.UserState.Builder usb = Mumble.UserState.newBuilder();
- usb.setSession(session);
- usb.setComment(comment);
- mConnection.sendTCPMessage(usb.build(), JumbleTCPMessageType.UserState);
- }
+ @Override
+ public void setUserComment(int session, String comment) {
+ Mumble.UserState.Builder usb = Mumble.UserState.newBuilder();
+ usb.setSession(session);
+ usb.setComment(comment);
+ getConnection().sendTCPMessage(usb.build(), JumbleTCPMessageType.UserState);
+ }
- @Override
- public void setPrioritySpeaker(int session, boolean priority) throws RemoteException {
- Mumble.UserState.Builder usb = Mumble.UserState.newBuilder();
- usb.setSession(session);
- usb.setPrioritySpeaker(priority);
- mConnection.sendTCPMessage(usb.build(), JumbleTCPMessageType.UserState);
- }
+ @Override
+ public void setPrioritySpeaker(int session, boolean priority) {
+ Mumble.UserState.Builder usb = Mumble.UserState.newBuilder();
+ usb.setSession(session);
+ usb.setPrioritySpeaker(priority);
+ getConnection().sendTCPMessage(usb.build(), JumbleTCPMessageType.UserState);
+ }
- @Override
- public void removeChannel(int channel) throws RemoteException {
- Mumble.ChannelRemove.Builder crb = Mumble.ChannelRemove.newBuilder();
- crb.setChannelId(channel);
- mConnection.sendTCPMessage(crb.build(), JumbleTCPMessageType.ChannelRemove);
- }
+ @Override
+ public void removeChannel(int channel) {
+ Mumble.ChannelRemove.Builder crb = Mumble.ChannelRemove.newBuilder();
+ crb.setChannelId(channel);
+ getConnection().sendTCPMessage(crb.build(), JumbleTCPMessageType.ChannelRemove);
+ }
- @Override
- public void setMuteDeafState(int session, boolean mute, boolean deaf) throws RemoteException {
- Mumble.UserState.Builder usb = Mumble.UserState.newBuilder();
- usb.setSession(session);
- usb.setMute(mute);
- usb.setDeaf(deaf);
- if (!mute) usb.setSuppress(false);
- mConnection.sendTCPMessage(usb.build(), JumbleTCPMessageType.UserState);
- }
+ @Override
+ public void setMuteDeafState(int session, boolean mute, boolean deaf) {
+ Mumble.UserState.Builder usb = Mumble.UserState.newBuilder();
+ usb.setSession(session);
+ usb.setMute(mute);
+ usb.setDeaf(deaf);
+ if (!mute) usb.setSuppress(false);
+ getConnection().sendTCPMessage(usb.build(), JumbleTCPMessageType.UserState);
+ }
- @Override
- public void setSelfMuteDeafState(boolean mute, boolean deaf) throws RemoteException {
- Mumble.UserState.Builder usb = Mumble.UserState.newBuilder();
- usb.setSelfMute(mute);
- usb.setSelfDeaf(deaf);
- mConnection.sendTCPMessage(usb.build(), JumbleTCPMessageType.UserState);
- }
+ @Override
+ public void setSelfMuteDeafState(boolean mute, boolean deaf) {
+ Mumble.UserState.Builder usb = Mumble.UserState.newBuilder();
+ usb.setSelfMute(mute);
+ usb.setSelfDeaf(deaf);
+ getConnection().sendTCPMessage(usb.build(), JumbleTCPMessageType.UserState);
+ }
- @Override
- public void registerObserver(IJumbleObserver observer) throws RemoteException {
- mCallbacks.registerObserver(observer);
- }
+ public void registerObserver(IJumbleObserver observer) {
+ mCallbacks.registerObserver(observer);
+ }
- @Override
- public void unregisterObserver(IJumbleObserver observer) throws RemoteException {
- mCallbacks.unregisterObserver(observer);
+ public void unregisterObserver(IJumbleObserver observer) {
+ mCallbacks.unregisterObserver(observer);
+ }
+
+
+ /**
+ * The current connection state of the service.
+ */
+ public enum ConnectionState {
+ /**
+ * The default state of Jumble, before connection to a server and after graceful/expected
+ * disconnection from a server.
+ */
+ DISCONNECTED,
+ /**
+ * A connection to the server is currently in progress.
+ */
+ CONNECTING,
+ /**
+ * Jumble has received all data necessary for normal protocol communication with the server.
+ */
+ CONNECTED,
+ /**
+ * The connection was lost due to either a kick/ban or socket I/O error.
+ * Jumble may be reconnecting in this state.
+ * @see #isReconnecting()
+ * @see #cancelReconnect()
+ */
+ CONNECTION_LOST
+ }
+
+ public static class JumbleBinder extends Binder {
+ private final IJumbleService mService;
+
+ private JumbleBinder(IJumbleService service) {
+ mService = service;
}
- @Override
- public boolean reconfigure(Bundle extras) throws RemoteException {
- try {
- return configureExtras(extras);
- } catch (AudioException e) {
- e.printStackTrace();
- // TODO
- return true;
- }
+ public IJumbleService getService() {
+ return mService;
}
}
}
diff --git a/src/main/java/com/morlunk/jumble/exception/NotConnectedException.java b/src/main/java/com/morlunk/jumble/exception/NotConnectedException.java
new file mode 100644
index 0000000..c81db73
--- /dev/null
+++ b/src/main/java/com/morlunk/jumble/exception/NotConnectedException.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2015 Andrew Comminos <andrew@comminos.com>
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.morlunk.jumble.exception;
+
+/**
+ * Thrown when a Jumble connection has not yet been established.
+ * Created by andrew on 24/10/15.
+ */
+public class NotConnectedException extends Exception {
+ public NotConnectedException() {
+ super("Not yet connected");
+ }
+
+ public NotConnectedException(String message) {
+ super(message);
+ }
+}
diff --git a/src/main/java/com/morlunk/jumble/exception/NotSynchronizedException.java b/src/main/java/com/morlunk/jumble/exception/NotSynchronizedException.java
new file mode 100644
index 0000000..c65fd15
--- /dev/null
+++ b/src/main/java/com/morlunk/jumble/exception/NotSynchronizedException.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2015 Andrew Comminos <andrew@comminos.com>
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.morlunk.jumble.exception;
+
+/**
+ * Called when Jumble has not yet received the ServerSync message from the server.
+ * Created by andrew on 24/10/15.
+ */
+public class NotSynchronizedException extends Exception {
+ public NotSynchronizedException() {
+ super("Not yet synchronized");
+ }
+
+ public NotSynchronizedException(String message) {
+ super(message);
+ }
+}
diff --git a/src/main/java/com/morlunk/jumble/model/Channel.java b/src/main/java/com/morlunk/jumble/model/Channel.java
index 7edc95f..142754f 100644
--- a/src/main/java/com/morlunk/jumble/model/Channel.java
+++ b/src/main/java/com/morlunk/jumble/model/Channel.java
@@ -21,7 +21,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-public final class Channel extends IChannel.Stub implements Comparable<Channel> {
+public final class Channel implements IChannel, Comparable<Channel> {
private int mId;
private int mPosition;
private int mLevel;
@@ -68,10 +68,12 @@ public final class Channel extends IChannel.Stub implements Comparable<Channel>
mUsers.remove(user);
}
+ @Override
public List<User> getUsers() {
return Collections.unmodifiableList(mUsers);
}
+ @Override
public int getId() {
return mId;
}
@@ -80,6 +82,7 @@ public final class Channel extends IChannel.Stub implements Comparable<Channel>
this.mId = mId;
}
+ @Override
public int getPosition() {
return mPosition;
}
@@ -88,6 +91,7 @@ public final class Channel extends IChannel.Stub implements Comparable<Channel>
this.mPosition = mPosition;
}
+ @Override
public boolean isTemporary() {
return mTemporary;
}
@@ -96,6 +100,7 @@ public final class Channel extends IChannel.Stub implements Comparable<Channel>
this.mTemporary = mTemporary;
}
+ @Override
public Channel getParent() {
return mParent;
}
@@ -104,6 +109,7 @@ public final class Channel extends IChannel.Stub implements Comparable<Channel>
this.mParent = mParent;
}
+ @Override
public String getName() {
return mName;
}
@@ -112,6 +118,7 @@ public final class Channel extends IChannel.Stub implements Comparable<Channel>
this.mName = mName;
}
+ @Override
public String getDescription() {
return mDescription;
}
@@ -120,6 +127,7 @@ public final class Channel extends IChannel.Stub implements Comparable<Channel>
this.mDescription = mDescription;
}
+ @Override
public byte[] getDescriptionHash() {
return mDescriptionHash;
}
@@ -128,6 +136,7 @@ public final class Channel extends IChannel.Stub implements Comparable<Channel>
this.mDescriptionHash = mDescriptionHash;
}
+ @Override
public List<Channel> getSubchannels() {
return Collections.unmodifiableList(mSubchannels);
}
@@ -147,6 +156,7 @@ public final class Channel extends IChannel.Stub implements Comparable<Channel>
mSubchannels.remove(channel);
}
+ @Override
public List<Channel> getLinks() {
return Collections.unmodifiableList(mLinks);
}
@@ -183,6 +193,7 @@ public final class Channel extends IChannel.Stub implements Comparable<Channel>
return userCount;
}
+ @Override
public int getPermissions() {
return mPermissions;
}
diff --git a/src/main/java/com/morlunk/jumble/model/IChannel.java b/src/main/java/com/morlunk/jumble/model/IChannel.java
new file mode 100644
index 0000000..fc9d8e7
--- /dev/null
+++ b/src/main/java/com/morlunk/jumble/model/IChannel.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2015 Andrew Comminos <andrew@comminos.com>
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.morlunk.jumble.model;
+
+import java.util.List;
+
+public interface IChannel {
+ List<? extends IUser> getUsers();
+
+ int getId();
+
+ int getPosition();
+
+ boolean isTemporary();
+
+ IChannel getParent();
+
+ String getName();
+
+ String getDescription();
+
+ byte[] getDescriptionHash();
+
+ List<? extends IChannel> getSubchannels();
+
+ int getSubchannelUserCount();
+
+ List<? extends IChannel> getLinks();
+
+ int getPermissions();
+}
diff --git a/src/main/java/com/morlunk/jumble/model/IMessage.java b/src/main/java/com/morlunk/jumble/model/IMessage.java
new file mode 100644
index 0000000..9a3ec2c
--- /dev/null
+++ b/src/main/java/com/morlunk/jumble/model/IMessage.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2015 Andrew Comminos <andrew@comminos.com>
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.morlunk.jumble.model;
+
+import java.util.List;
+
+public interface IMessage {
+ int getActor();
+
+ String getActorName();
+
+ List<Channel> getTargetChannels();
+
+ List<Channel> getTargetTrees();
+
+ List<User> getTargetUsers();
+
+ String getMessage();
+
+ long getReceivedTime();
+}
diff --git a/src/main/java/com/morlunk/jumble/model/IUser.java b/src/main/java/com/morlunk/jumble/model/IUser.java
new file mode 100644
index 0000000..5f18246
--- /dev/null
+++ b/src/main/java/com/morlunk/jumble/model/IUser.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2015 Andrew Comminos <andrew@comminos.com>
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.morlunk.jumble.model;
+
+/**
+ * Created by andrew on 15/10/15.
+ */
+public interface IUser {
+ int getSession();
+
+ Channel getChannel();
+
+ int getUserId();
+
+ String getName();
+
+ String getComment();
+
+ byte[] getCommentHash();
+
+ byte[] getTexture();
+
+ byte[] getTextureHash();
+
+ String getHash();
+
+ boolean isMuted();
+
+ boolean isDeafened();
+
+ boolean isSuppressed();
+
+ boolean isSelfMuted();
+
+ boolean isSelfDeafened();
+
+ boolean isPrioritySpeaker();
+
+ boolean isRecording();
+
+ boolean isLocalMuted();
+
+ boolean isLocalIgnored();
+
+ void setLocalMuted(boolean muted);
+
+ void setLocalIgnored(boolean ignored);
+
+ TalkState getTalkState();
+}
diff --git a/src/main/java/com/morlunk/jumble/model/Message.java b/src/main/java/com/morlunk/jumble/model/Message.java
index 17270da..202e803 100644
--- a/src/main/java/com/morlunk/jumble/model/Message.java
+++ b/src/main/java/com/morlunk/jumble/model/Message.java
@@ -32,7 +32,7 @@ import java.util.List;
* as the actor may no longer be on the server.
* Created by andrew on 03/12/13.
*/
-public class Message extends IMessage.Stub {
+public class Message implements IMessage {
private int mActor;
private String mActorName;
private List<Channel> mChannels;
@@ -58,30 +58,37 @@ public class Message extends IMessage.Stub {
mTrees = trees;
mUsers = users;
}
+ @Override
public int getActor() {
return mActor;
}
+ @Override
public String getActorName() {
return mActorName;
}
+ @Override
public List<Channel> getTargetChannels() {
return Collections.unmodifiableList(mChannels);
}
+ @Override
public List<Channel> getTargetTrees() {
return Collections.unmodifiableList(mTrees);
}
+ @Override
public List<User> getTargetUsers() {
return Collections.unmodifiableList(mUsers);
}
+ @Override
public String getMessage() {
return mMessage;
}
+ @Override
public long getReceivedTime() {
return mReceivedTime;
}
diff --git a/src/main/java/com/morlunk/jumble/model/User.java b/src/main/java/com/morlunk/jumble/model/User.java
index 559cbdf..3bfd31d 100644
--- a/src/main/java/com/morlunk/jumble/model/User.java
+++ b/src/main/java/com/morlunk/jumble/model/User.java
@@ -19,7 +19,7 @@ package com.morlunk.jumble.model;
import com.google.protobuf.ByteString;
-public class User extends IUser.Stub implements Comparable<User> {
+public class User implements IUser, Comparable<User> {
private int mSession;
private int mId = -1;
@@ -60,10 +60,12 @@ public class User extends IUser.Stub implements Comparable<User> {
mName = name;
}
+ @Override
public int getSession() {
return mSession;
}
+ @Override
public Channel getChannel() {
return mChannel;
}
@@ -82,6 +84,7 @@ public class User extends IUser.Stub implements Comparable<User> {
mChannel.addUser(this);
}
+ @Override
public int getUserId() {
return mId;
}
@@ -90,6 +93,7 @@ public class User extends IUser.Stub implements Comparable<User> {
this.mId = mId;
}
+ @Override
public String getName() {
return mName;
}
@@ -98,6 +102,7 @@ public class User extends IUser.Stub implements Comparable<User> {
this.mName = mName;
}
+ @Override
public String getComment() {
return mComment;
}
@@ -106,6 +111,7 @@ public class User extends IUser.Stub implements Comparable<User> {
this.mComment = mComment;
}
+ @Override
public byte[] getCommentHash() {
return mCommentHash != null ? mCommentHash.toByteArray() : null;
}
@@ -114,6 +120,7 @@ public class User extends IUser.Stub implements Comparable<User> {
mCommentHash = commentHash;
}
+ @Override
public byte[] getTexture() {
return mTexture != null ? mTexture.toByteArray() : null;
}
@@ -122,6 +129,7 @@ public class User extends IUser.Stub implements Comparable<User> {
mTexture = texture;
}
+ @Override
public byte[] getTextureHash() {
return mTextureHash != null ? mTextureHash.toByteArray() : null;
}
@@ -130,6 +138,7 @@ public class User extends IUser.Stub implements Comparable<User> {
mTextureHash = textureHash;
}
+ @Override
public String getHash() {
return mHash;
}
@@ -138,6 +147,7 @@ public class User extends IUser.Stub implements Comparable<User> {
this.mHash = mHash;
}
+ @Override
public boolean isMuted() {
return mMuted;
}
@@ -146,6 +156,7 @@ public class User extends IUser.Stub implements Comparable<User> {
this.mMuted = mMuted;
}
+ @Override
public boolean isDeafened() {
return mDeafened;
}
@@ -154,6 +165,7 @@ public class User extends IUser.Stub implements Comparable<User> {
this.mDeafened = mDeafened;
}
+ @Override
public boolean isSuppressed() {
return mSuppressed;
}
@@ -162,6 +174,7 @@ public class User extends IUser.Stub implements Comparable<User> {
this.mSuppressed = mSuppressed;
}
+ @Override
public boolean isSelfMuted() {
return mSelfMuted;
}
@@ -170,6 +183,7 @@ public class User extends IUser.Stub implements Comparable<User> {
this.mSelfMuted = mSelfMuted;
}
+ @Override
public boolean isSelfDeafened() {
return mSelfDeafened;
}
@@ -178,6 +192,7 @@ public class User extends IUser.Stub implements Comparable<User> {
this.mSelfDeafened = mSelfDeafened;
}
+ @Override
public boolean isPrioritySpeaker() {
return mPrioritySpeaker;
}
@@ -186,6 +201,7 @@ public class User extends IUser.Stub implements Comparable<User> {
this.mPrioritySpeaker = mPrioritySpeaker;
}
+ @Override
public boolean isRecording() {
return mRecording;
}
@@ -194,6 +210,7 @@ public class User extends IUser.Stub implements Comparable<User> {
this.mRecording = mRecording;
}
+ @Override
public boolean isLocalMuted() {
return mLocalMuted;
}
@@ -202,6 +219,7 @@ public class User extends IUser.Stub implements Comparable<User> {
this.mLocalMuted = mLocalMuted;
}
+ @Override
public boolean isLocalIgnored() {
return mLocalIgnored;
}
@@ -210,6 +228,7 @@ public class User extends IUser.Stub implements Comparable<User> {
mLocalIgnored = localIgnored;
}
+ @Override
public TalkState getTalkState() {
return mTalkState;
}
diff --git a/src/main/java/com/morlunk/jumble/net/JumbleConnection.java b/src/main/java/com/morlunk/jumble/net/JumbleConnection.java
index 2bbbad9..6f54199 100644
--- a/src/main/java/com/morlunk/jumble/net/JumbleConnection.java
+++ b/src/main/java/com/morlunk/jumble/net/JumbleConnection.java
@@ -25,6 +25,8 @@ import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.Message;
import com.morlunk.jumble.Constants;
+import com.morlunk.jumble.exception.NotConnectedException;
+import com.morlunk.jumble.exception.NotSynchronizedException;
import com.morlunk.jumble.protobuf.Mumble;
import com.morlunk.jumble.protocol.JumbleTCPMessageListener;
import com.morlunk.jumble.protocol.JumbleUDPMessageListener;
@@ -398,31 +400,45 @@ public class JumbleConnection implements JumbleTCP.TCPConnectionListener, Jumble
mTrustStoreFormat = format;
}
- public int getServerVersion() {
+ public int getServerVersion() throws NotSynchronizedException {
+ if (!isSynchronized())
+ throw new NotSynchronizedException();
return mServerVersion;
}
- public String getServerRelease() {
+ public String getServerRelease() throws NotSynchronizedException {
+ if (!isSynchronized())
+ throw new NotSynchronizedException();
return mServerRelease;
}
- public String getServerOSName() {
+ public String getServerOSName() throws NotSynchronizedException {
+ if (!isSynchronized())
+ throw new NotSynchronizedException();
return mServerOSName;
}
- public String getServerOSVersion() {
+ public String getServerOSVersion() throws NotSynchronizedException {
+ if (!isSynchronized())
+ throw new NotSynchronizedException();
return mServerOSVersion;
}
- public long getTCPLatency() {
+ public long getTCPLatency() throws NotConnectedException {
+ if (!isConnected())
+ throw new NotConnectedException();
return mLastTCPPing;
}
- public long getUDPLatency() {
+ public long getUDPLatency() throws NotConnectedException {
+ if (!isConnected())
+ throw new NotConnectedException();
return mLastUDPPing;
}
- public int getSession() {
+ public int getSession() throws NotSynchronizedException {
+ if (!isSynchronized())
+ throw new NotSynchronizedException("Session is set during synchronization");
return mSession;
}
@@ -430,11 +446,15 @@ public class JumbleConnection implements JumbleTCP.TCPConnectionListener, Jumble
* Returns the server-reported maximum input bandwidth, or -1 if not set.
* @return the input bandwidth in bps, or -1 if not set.
*/
- public int getMaxBandwidth() {
+ public int getMaxBandwidth() throws NotSynchronizedException {
+ if (!isSynchronized())
+ throw new NotSynchronizedException();
return mMaxBandwidth;
}
- public JumbleUDPMessageType getCodec() {
+ public JumbleUDPMessageType getCodec() throws NotSynchronizedException {
+ if (!isSynchronized())
+ throw new NotSynchronizedException();
return mCodec;
}
diff --git a/src/main/java/com/morlunk/jumble/protocol/ModelHandler.java b/src/main/java/com/morlunk/jumble/protocol/ModelHandler.java
index 973fb3a..a14b803 100644
--- a/src/main/java/com/morlunk/jumble/protocol/ModelHandler.java
+++ b/src/main/java/com/morlunk/jumble/protocol/ModelHandler.java
@@ -24,13 +24,13 @@ import android.os.RemoteException;
import android.util.Log;
import com.morlunk.jumble.Constants;
-import com.morlunk.jumble.IJumbleObserver;
import com.morlunk.jumble.R;
import com.morlunk.jumble.model.Channel;
import com.morlunk.jumble.model.Message;
import com.morlunk.jumble.model.User;
import com.morlunk.jumble.protobuf.Mumble;
import com.morlunk.jumble.protocol.JumbleTCPMessageListener;
+import com.morlunk.jumble.util.IJumbleObserver;
import com.morlunk.jumble.util.JumbleLogger;
import com.morlunk.jumble.util.MessageFormatter;
@@ -165,15 +165,10 @@ public class ModelHandler extends JumbleTCPMessageListener.Stub {
channel.addLink(mChannels.get(link));
}
- final Channel finalChannel = channel;
- try {
- if(newChannel)
- mObserver.onChannelAdded(finalChannel);
- else
- mObserver.onChannelStateUpdated(finalChannel);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
+ if(newChannel)
+ mObserver.onChannelAdded(channel);
+ else
+ mObserver.onChannelStateUpdated(channel);
}
@Override
@@ -185,11 +180,7 @@ public class ModelHandler extends JumbleTCPMessageListener.Stub {
if(parent != null) {
parent.removeSubchannel(channel);
}
- try {
- mObserver.onChannelRemoved(channel);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
+ mObserver.onChannelRemoved(channel);
}
}
@@ -204,11 +195,7 @@ public class ModelHandler extends JumbleTCPMessageListener.Stub {
channel.setPermissions(msg.getPermissions());
if(msg.getChannelId() == 0) // If we're provided permissions for the root channel, we'll apply these as our server permissions.
mPermissions = channel.getPermissions();
- try {
- mObserver.onChannelPermissionsUpdated(channel);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
+ mObserver.onChannelPermissionsUpdated(channel);
}
}
@@ -343,11 +330,7 @@ public class ModelHandler extends JumbleTCPMessageListener.Stub {
user.setChannel(channel);
if(!newUser) {
- try {
- mObserver.onUserJoinedChannel(finalUser, channel, old);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
+ mObserver.onUserJoinedChannel(finalUser, channel, old);
}
Channel sessionChannel = self != null ? self.getChannel() : null;
@@ -402,16 +385,10 @@ public class ModelHandler extends JumbleTCPMessageListener.Stub {
if(msg.hasComment())
user.setComment(msg.getComment());
- final boolean finalNewUser = newUser;
-
- try {
- if(finalNewUser)
- mObserver.onUserConnected(finalUser);
- else
- mObserver.onUserStateUpdated(finalUser);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
+ if (newUser)
+ mObserver.onUserConnected(user);
+ else
+ mObserver.onUserStateUpdated(user);
}
@Override
@@ -428,12 +405,7 @@ public class ModelHandler extends JumbleTCPMessageListener.Stub {
mLogger.logInfo(mContext.getString(R.string.chat_notify_disconnected, MessageFormatter.highlightString(user.getName())));
user.setChannel(null);
-
- try {
- mObserver.onUserRemoved(user, reason);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
+ mObserver.onUserRemoved(user, reason);
}
@Override
@@ -466,11 +438,7 @@ public class ModelHandler extends JumbleTCPMessageListener.Stub {
else reason = mContext.getString(R.string.perm_denied);
}
- try {
- mObserver.onPermissionDenied(reason);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
+ mObserver.onPermissionDenied(reason);
}
@Override
@@ -490,11 +458,7 @@ public class ModelHandler extends JumbleTCPMessageListener.Stub {
String actorName = sender != null ? sender.getName() : mContext.getString(R.string.server);
Message message = new Message(msg.getActor(), actorName, channels, trees, users, msg.getMessage());
- try {
- mObserver.onMessageLogged(message);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
+ mObserver.onMessageLogged(message);
}
@Override
diff --git a/src/main/java/com/morlunk/jumble/util/IJumbleObserver.java b/src/main/java/com/morlunk/jumble/util/IJumbleObserver.java
new file mode 100644
index 0000000..d167da3
--- /dev/null
+++ b/src/main/java/com/morlunk/jumble/util/IJumbleObserver.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2015 Andrew Comminos <andrew@comminos.com>
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.morlunk.jumble.util;
+
+import com.morlunk.jumble.model.IChannel;
+import com.morlunk.jumble.model.IMessage;
+import com.morlunk.jumble.model.IUser;
+
+import java.security.cert.X509Certificate;
+
+/**
+ * Created by andrew on 18/10/15.
+ */
+public interface IJumbleObserver {
+ void onConnected();
+
+ void onConnecting();
+
+ void onDisconnected(JumbleException e);
+
+ void onTLSHandshakeFailed(X509Certificate[] chain);
+
+ void onChannelAdded(IChannel channel);
+
+ void onChannelStateUpdated(IChannel channel);
+
+ void onChannelRemoved(IChannel channel);
+
+ void onChannelPermissionsUpdated(IChannel channel);
+
+ void onUserConnected(IUser user);
+
+ void onUserStateUpdated(IUser user);
+
+ void onUserTalkStateUpdated(IUser user);
+
+ void onUserJoinedChannel(IUser user, IChannel newChannel, IChannel oldChannel);
+
+ void onUserRemoved(IUser user, String reason);
+
+ void onPermissionDenied(String reason);
+
+ void onMessageLogged(IMessage message);
+
+ void onLogInfo(String message);
+
+ void onLogWarning(String message);
+
+ void onLogError(String message);
+}
diff --git a/src/main/java/com/morlunk/jumble/util/JumbleCallbacks.java b/src/main/java/com/morlunk/jumble/util/JumbleCallbacks.java
index 1f67a16..5fc1107 100644
--- a/src/main/java/com/morlunk/jumble/util/JumbleCallbacks.java
+++ b/src/main/java/com/morlunk/jumble/util/JumbleCallbacks.java
@@ -17,214 +17,158 @@
package com.morlunk.jumble.util;
-import android.os.RemoteCallbackList;
-import android.os.RemoteException;
-
-import com.morlunk.jumble.IJumbleObserver;
import com.morlunk.jumble.model.IChannel;
import com.morlunk.jumble.model.IMessage;
import com.morlunk.jumble.model.IUser;
+import org.spongycastle.jcajce.provider.asymmetric.X509;
+
+import java.security.cert.X509Certificate;
+import java.util.HashSet;
+import java.util.Set;
+
/**
* A composite wrapper around Jumble observers to easily broadcast to each observer.
* Created by andrew on 12/07/14.
*/
-public class JumbleCallbacks extends JumbleObserver.Stub {
- private final RemoteCallbackList<IJumbleObserver> mCallbacks;
+public class JumbleCallbacks implements IJumbleObserver {
+ private final Set<IJumbleObserver> mCallbacks;
public JumbleCallbacks() {
- mCallbacks = new RemoteCallbackList<IJumbleObserver>();
+ mCallbacks = new HashSet<>();
}
public void registerObserver(IJumbleObserver observer) {
- mCallbacks.register(observer);
+ mCallbacks.add(observer);
}
public void unregisterObserver(IJumbleObserver observer) {
- mCallbacks.unregister(observer);
- }
-
- public void kill() {
- mCallbacks.kill();
+ mCallbacks.remove(observer);
}
@Override
- public void onConnected() throws RemoteException {
- int i = mCallbacks.beginBroadcast();
- while(i > 0) {
- i--;
- mCallbacks.getBroadcastItem(i).onConnected();
+ public void onConnected() {
+ for (IJumbleObserver observer : mCallbacks) {
+ observer.onConnected();
}
- mCallbacks.finishBroadcast();
}
@Override
- public void onConnecting() throws RemoteException {
- int i = mCallbacks.beginBroadcast();
- while(i > 0) {
- i--;
- mCallbacks.getBroadcastItem(i).onConnecting();
+ public void onConnecting() {
+ for (IJumbleObserver observer : mCallbacks) {
+ observer.onConnecting();
}
- mCallbacks.finishBroadcast();
}
@Override
- public void onDisconnected(JumbleException e) throws RemoteException {
- int i = mCallbacks.beginBroadcast();
- while(i > 0) {
- i--;
- mCallbacks.getBroadcastItem(i).onDisconnected(e);
+ public void onDisconnected(JumbleException e) {
+ for (IJumbleObserver observer : mCallbacks) {
+ observer.onDisconnected(e);
}
- mCallbacks.finishBroadcast();
}
@Override
- public void onTLSHandshakeFailed(ParcelableByteArray cert) throws RemoteException {
- int i = mCallbacks.beginBroadcast();
- while(i > 0) {
- i--;
- mCallbacks.getBroadcastItem(i).onTLSHandshakeFailed(cert);
+ public void onTLSHandshakeFailed(X509Certificate[] chain) {
+ for (IJumbleObserver observer : mCallbacks) {
+ observer.onTLSHandshakeFailed(chain);
}
- mCallbacks.finishBroadcast();
}
@Override
- public void onChannelAdded(IChannel channel) throws RemoteException {
- int i = mCallbacks.beginBroadcast();
- while(i > 0) {
- i--;
- mCallbacks.getBroadcastItem(i).onChannelAdded(channel);
+ public void onChannelAdded(IChannel channel) {
+ for (IJumbleObserver observer : mCallbacks) {
+ observer.onChannelAdded(channel);
}
- mCallbacks.finishBroadcast();
}
@Override
- public void onChannelStateUpdated(IChannel channel) throws RemoteException {
- int i = mCallbacks.beginBroadcast();
- while(i > 0) {
- i--;
- mCallbacks.getBroadcastItem(i).onChannelStateUpdated(channel);
+ public void onChannelStateUpdated(IChannel channel) {
+ for (IJumbleObserver observer : mCallbacks) {
+ observer.onChannelStateUpdated(channel);
}
- mCallbacks.finishBroadcast();
}
@Override
- public void onChannelRemoved(IChannel channel) throws RemoteException {
- int i = mCallbacks.beginBroadcast();
- while(i > 0) {
- i--;
- mCallbacks.getBroadcastItem(i).onChannelRemoved(channel);
+ public void onChannelRemoved(IChannel channel) {
+ for (IJumbleObserver observer : mCallbacks) {
+ observer.onChannelRemoved(channel);
}
- mCallbacks.finishBroadcast();
}
@Override
- public void onChannelPermissionsUpdated(IChannel channel) throws RemoteException {
- int i = mCallbacks.beginBroadcast();
- while(i > 0) {
- i--;
- mCallbacks.getBroadcastItem(i).onChannelPermissionsUpdated(channel);
+ public void onChannelPermissionsUpdated(IChannel channel) {
+ for (IJumbleObserver observer : mCallbacks) {
+ observer.onChannelPermissionsUpdated(channel);
}
- mCallbacks.finishBroadcast();
}
@Override
- public void onUserConnected(IUser user) throws RemoteException {
- int i = mCallbacks.beginBroadcast();
- while(i > 0) {
- i--;
- mCallbacks.getBroadcastItem(i).onUserConnected(user);
+ public void onUserConnected(IUser user) {
+ for (IJumbleObserver observer : mCallbacks) {
+ observer.onUserConnected(user);
}
- mCallbacks.finishBroadcast();
}
@Override
- public void onUserStateUpdated(IUser user) throws RemoteException {
- int i = mCallbacks.beginBroadcast();
- while(i > 0) {
- i--;
- mCallbacks.getBroadcastItem(i).onUserStateUpdated(user);
+ public void onUserStateUpdated(IUser user) {
+ for (IJumbleObserver observer : mCallbacks) {
+ observer.onUserStateUpdated(user);
}
- mCallbacks.finishBroadcast();
}
@Override
- public void onUserTalkStateUpdated(IUser user) throws RemoteException {
- int i = mCallbacks.beginBroadcast();
- while(i > 0) {
- i--;
- mCallbacks.getBroadcastItem(i).onUserTalkStateUpdated(user);
+ public void onUserTalkStateUpdated(IUser user) {
+ for (IJumbleObserver observer : mCallbacks) {
+ observer.onUserTalkStateUpdated(user);
}
- mCallbacks.finishBroadcast();
}
@Override
- public void onUserJoinedChannel(IUser user, IChannel newChannel, IChannel oldChannel) throws RemoteException {
- int i = mCallbacks.beginBroadcast();
- while(i > 0) {
- i--;
- mCallbacks.getBroadcastItem(i).onUserJoinedChannel(user, newChannel, oldChannel);
+ public void onUserJoinedChannel(IUser user, IChannel newChannel, IChannel oldChannel) {
+ for (IJumbleObserver observer : mCallbacks) {
+ observer.onUserJoinedChannel(user, newChannel, oldChannel);
}
- mCallbacks.finishBroadcast();
}
@Override
- public void onUserRemoved(IUser user, String reason) throws RemoteException {
- int i = mCallbacks.beginBroadcast();
- while(i > 0) {
- i--;
- mCallbacks.getBroadcastItem(i).onUserRemoved(user, reason);
+ public void onUserRemoved(IUser user, String reason) {
+ for (IJumbleObserver observer : mCallbacks) {
+ observer.onUserRemoved(user, reason);
}
- mCallbacks.finishBroadcast();
}
@Override
- public void onPermissionDenied(String reason) throws RemoteException {
- int i = mCallbacks.beginBroadcast();
- while(i > 0) {
- i--;
- mCallbacks.getBroadcastItem(i).onPermissionDenied(reason);
+ public void onPermissionDenied(String reason) {
+ for (IJumbleObserver observer : mCallbacks) {
+ observer.onPermissionDenied(reason);
}
- mCallbacks.finishBroadcast();
}
@Override
- public void onMessageLogged(IMessage message) throws RemoteException {
- int i = mCallbacks.beginBroadcast();
- while(i > 0) {
- i--;
- mCallbacks.getBroadcastItem(i).onMessageLogged(message);
+ public void onMessageLogged(IMessage message) {
+ for (IJumbleObserver observer : mCallbacks) {
+ observer.onMessageLogged(message);
}
- mCallbacks.finishBroadcast();
}
@Override
- public void onLogInfo(String message) throws RemoteException {
- int i = mCallbacks.beginBroadcast();
- while(i > 0) {
- i--;
- mCallbacks.getBroadcastItem(i).onLogInfo(message);
+ public void onLogInfo(String message) {
+ for (IJumbleObserver observer : mCallbacks) {
+ observer.onLogInfo(message);
}
- mCallbacks.finishBroadcast();
}
@Override
- public void onLogWarning(String message) throws RemoteException {
- int i = mCallbacks.beginBroadcast();
- while(i > 0) {
- i--;
- mCallbacks.getBroadcastItem(i).onLogWarning(message);
+ public void onLogWarning(String message) {
+ for (IJumbleObserver observer : mCallbacks) {
+ observer.onLogWarning(message);
}
- mCallbacks.finishBroadcast();
}
@Override
- public void onLogError(String message) throws RemoteException {
- int i = mCallbacks.beginBroadcast();
- while(i > 0) {
- i--;
- mCallbacks.getBroadcastItem(i).onLogError(message);
+ public void onLogError(String message) {
+ for (IJumbleObserver observer : mCallbacks) {
+ observer.onLogError(message);
}
- mCallbacks.finishBroadcast();
}
}
diff --git a/src/main/java/com/morlunk/jumble/util/JumbleObserver.java b/src/main/java/com/morlunk/jumble/util/JumbleObserver.java
index 3c51383..91f2751 100644
--- a/src/main/java/com/morlunk/jumble/util/JumbleObserver.java
+++ b/src/main/java/com/morlunk/jumble/util/JumbleObserver.java
@@ -17,109 +17,104 @@
package com.morlunk.jumble.util;
-import android.os.RemoteException;
-
-import com.morlunk.jumble.IJumbleObserver;
-import com.morlunk.jumble.model.Channel;
import com.morlunk.jumble.model.IChannel;
import com.morlunk.jumble.model.IMessage;
import com.morlunk.jumble.model.IUser;
-import com.morlunk.jumble.model.Message;
-import com.morlunk.jumble.model.User;
+
+import java.security.cert.X509Certificate;
/**
* Stub class for Jumble service observation.
* Created by andrew on 31/07/13.
*/
-public class JumbleObserver extends IJumbleObserver.Stub {
+public class JumbleObserver implements IJumbleObserver {
@Override
- public void onConnected() throws RemoteException {
+ public void onConnected() {
}
@Override
- public void onConnecting() throws RemoteException {
+ public void onConnecting() {
}
@Override
- public void onDisconnected(JumbleException e) throws RemoteException {
+ public void onDisconnected(JumbleException e) {
}
@Override
- public void onTLSHandshakeFailed(ParcelableByteArray cert) throws RemoteException {
+ public void onTLSHandshakeFailed(X509Certificate[] chain) {
}
@Override
- public void onChannelAdded(IChannel channel) throws RemoteException {
+ public void onChannelAdded(IChannel channel) {
}
@Override
- public void onChannelStateUpdated(IChannel channel) throws RemoteException {
+ public void onChannelStateUpdated(IChannel channel) {
}
@Override
- public void onChannelRemoved(IChannel channel) throws RemoteException {
+ public void onChannelRemoved(IChannel channel) {
}
@Override
- public void onChannelPermissionsUpdated(IChannel channel) throws RemoteException {
+ public void onChannelPermissionsUpdated(IChannel channel) {
}
@Override
- public void onUserConnected(IUser user) throws RemoteException {
+ public void onUserConnected(IUser user) {
}
@Override
- public void onUserStateUpdated(IUser user) throws RemoteException {
+ public void onUserStateUpdated(IUser user) {
}
@Override
- public void onUserTalkStateUpdated(IUser user) throws RemoteException {
-
+ public void onUserTalkStateUpdated(IUser user) {
+
}
@Override
- public void onUserJoinedChannel(IUser user, IChannel newChannel, IChannel oldChannel) throws RemoteException {
+ public void onUserJoinedChannel(IUser user, IChannel newChannel, IChannel oldChannel) {
}
@Override
- public void onUserRemoved(IUser user, String reason) throws RemoteException {
+ public void onUserRemoved(IUser user, String reason) {
}
@Override
- public void onPermissionDenied(String reason) throws RemoteException {
+ public void onPermissionDenied(String reason) {
}
@Override
- public void onMessageLogged(IMessage message) throws RemoteException {
+ public void onMessageLogged(IMessage message) {
}
@Override
- public void onLogInfo(String message) throws RemoteException {
+ public void onLogInfo(String message) {
}
@Override
- public void onLogWarning(String message) throws RemoteException {
+ public void onLogWarning(String message) {
}
@Override
- public void onLogError(String message) throws RemoteException {
+ public void onLogError(String message) {
}
-
}
diff --git a/src/main/java/com/morlunk/jumble/util/ParcelableByteArray.java b/src/main/java/com/morlunk/jumble/util/ParcelableByteArray.java
deleted file mode 100644
index 801cb0a..0000000
--- a/src/main/java/com/morlunk/jumble/util/ParcelableByteArray.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2014 Andrew Comminos
- *
- * This program 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.
- *
- * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package com.morlunk.jumble.util;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Created by andrew on 05/04/14.
- */
-public class ParcelableByteArray implements Parcelable {
-
- private byte[] mByteArray;
-
- public ParcelableByteArray(byte[] array) {
- mByteArray = array;
- }
-
- private ParcelableByteArray(Parcel in) {
- int length = in.readInt();
- mByteArray = new byte[length];
- in.readByteArray(mByteArray);
- }
-
- public byte[] getBytes() {
- return mByteArray;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(mByteArray.length);
- dest.writeByteArray(mByteArray);
- }
-
- public static final Creator<ParcelableByteArray> CREATOR = new Creator<ParcelableByteArray>() {
-
- @Override
- public ParcelableByteArray createFromParcel(Parcel source) {
- return new ParcelableByteArray(source);
- }
-
- @Override
- public ParcelableByteArray[] newArray(int size) {
- return new ParcelableByteArray[size];
- }
- };
-}