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

github.com/acomminos/Plumble.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Comminos <andrew@comminos.com>2017-03-02 08:21:12 +0300
committerAndrew Comminos <andrew@comminos.com>2017-03-02 08:21:12 +0300
commit3fbbef140168f6bb8bb609c7976ef572083969d4 (patch)
tree6230fa488d291aa143e1a6711552ea63217f1b0b
parent4684fadb58112368e1651dbb65847e86fb4d97d8 (diff)
Update usage of connection-oriented calls to match new Jumble getSession API, improving stability.
-rw-r--r--app/src/main/java/com/morlunk/mumbleclient/app/PlumbleActivity.java51
-rw-r--r--app/src/main/java/com/morlunk/mumbleclient/channel/AccessTokenFragment.java8
-rw-r--r--app/src/main/java/com/morlunk/mumbleclient/channel/ChannelChatFragment.java61
-rw-r--r--app/src/main/java/com/morlunk/mumbleclient/channel/ChannelEditFragment.java23
-rw-r--r--app/src/main/java/com/morlunk/mumbleclient/channel/ChannelFragment.java73
-rw-r--r--app/src/main/java/com/morlunk/mumbleclient/channel/ChannelListAdapter.java41
-rw-r--r--app/src/main/java/com/morlunk/mumbleclient/channel/ChannelListFragment.java38
-rw-r--r--app/src/main/java/com/morlunk/mumbleclient/channel/ChannelMenu.java41
-rw-r--r--app/src/main/java/com/morlunk/mumbleclient/channel/ChannelSearchProvider.java40
-rw-r--r--app/src/main/java/com/morlunk/mumbleclient/channel/PermissionsPopupMenu.java10
-rw-r--r--app/src/main/java/com/morlunk/mumbleclient/channel/ServerInfoFragment.java22
-rw-r--r--app/src/main/java/com/morlunk/mumbleclient/channel/UserMenu.java5
-rw-r--r--app/src/main/java/com/morlunk/mumbleclient/channel/comment/ChannelDescriptionFragment.java4
-rw-r--r--app/src/main/java/com/morlunk/mumbleclient/channel/comment/UserCommentFragment.java8
-rw-r--r--app/src/main/java/com/morlunk/mumbleclient/service/IPlumbleService.java30
-rw-r--r--app/src/main/java/com/morlunk/mumbleclient/service/PlumbleOverlay.java5
-rw-r--r--app/src/main/java/com/morlunk/mumbleclient/service/PlumbleService.java36
-rw-r--r--app/src/main/java/com/morlunk/mumbleclient/service/ipc/TalkBroadcastReceiver.java10
-rw-r--r--app/src/main/java/com/morlunk/mumbleclient/util/JumbleServiceFragment.java3
-rw-r--r--app/src/main/java/com/morlunk/mumbleclient/util/JumbleServiceProvider.java3
m---------libraries/Jumble0
21 files changed, 312 insertions, 200 deletions
diff --git a/app/src/main/java/com/morlunk/mumbleclient/app/PlumbleActivity.java b/app/src/main/java/com/morlunk/mumbleclient/app/PlumbleActivity.java
index 0794ffd..b0cb4f2 100644
--- a/app/src/main/java/com/morlunk/mumbleclient/app/PlumbleActivity.java
+++ b/app/src/main/java/com/morlunk/mumbleclient/app/PlumbleActivity.java
@@ -31,7 +31,6 @@ import android.media.AudioManager;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
-import android.os.RemoteException;
import android.preference.PreferenceManager;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
@@ -51,9 +50,10 @@ import android.widget.ListView;
import android.widget.Toast;
import com.morlunk.jumble.IJumbleService;
-import com.morlunk.jumble.JumbleService;
+import com.morlunk.jumble.IJumbleSession;
import com.morlunk.jumble.model.Server;
import com.morlunk.jumble.protobuf.Mumble;
+import com.morlunk.jumble.util.JumbleDisconnectedException;
import com.morlunk.jumble.util.JumbleException;
import com.morlunk.jumble.util.JumbleObserver;
import com.morlunk.jumble.util.MumbleURLParser;
@@ -73,6 +73,7 @@ import com.morlunk.mumbleclient.preference.Preferences;
import com.morlunk.mumbleclient.servers.FavouriteServerListFragment;
import com.morlunk.mumbleclient.servers.PublicServerListFragment;
import com.morlunk.mumbleclient.servers.ServerEditFragment;
+import com.morlunk.mumbleclient.service.IPlumbleService;
import com.morlunk.mumbleclient.service.PlumbleService;
import com.morlunk.mumbleclient.util.JumbleServiceFragment;
import com.morlunk.mumbleclient.util.JumbleServiceProvider;
@@ -80,14 +81,11 @@ import com.morlunk.mumbleclient.util.PlumbleTrustStore;
import org.spongycastle.util.encoders.Hex;
-import java.io.ByteArrayInputStream;
-import java.io.File;
import java.net.MalformedURLException;
import java.security.KeyStore;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
@@ -103,7 +101,7 @@ public class PlumbleActivity extends ActionBarActivity implements ListView.OnIte
*/
public static final String EXTRA_DRAWER_FRAGMENT = "drawer_fragment";
- private PlumbleService mService;
+ private IPlumbleService mService;
private PlumbleDatabase mDatabase;
private Settings mSettings;
@@ -122,7 +120,7 @@ public class PlumbleActivity extends ActionBarActivity implements ListView.OnIte
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
- mService = (PlumbleService)((JumbleService.JumbleBinder) service).getService();
+ mService = ((PlumbleService.PlumbleBinder) service).getService();
mService.setSuppressNotifications(true);
mService.registerObserver(mObserver);
mService.clearChatNotifications(); // Clear chat notifications on resume.
@@ -133,7 +131,7 @@ public class PlumbleActivity extends ActionBarActivity implements ListView.OnIte
// Re-show server list if we're showing a fragment that depends on the service.
if(getSupportFragmentManager().findFragmentById(R.id.content_frame) instanceof JumbleServiceFragment &&
- !mService.isSynchronized()) {
+ !mService.isConnected()) {
loadDrawerFragment(DrawerAdapter.ITEM_FAVOURITES);
}
updateConnectionState(getService());
@@ -174,7 +172,7 @@ public class PlumbleActivity extends ActionBarActivity implements ListView.OnIte
@Override
public void onTLSHandshakeFailed(X509Certificate[] chain) {
- final Server lastServer = getService().getConnectedServer();
+ final Server lastServer = getService().getTargetServer();
if (chain.length == 0)
return;
@@ -262,10 +260,11 @@ public class PlumbleActivity extends ActionBarActivity implements ListView.OnIte
public void onDrawerStateChanged(int newState) {
super.onDrawerStateChanged(newState);
// Prevent push to talk from getting stuck on when the drawer is opened.
- if (getService() != null
- && getService().isSynchronized()
- && getService().isTalking() && !mSettings.isPushToTalkToggle()) {
- getService().setTalkingState(false);
+ if (getService() != null && getService().isConnected()) {
+ IJumbleSession session = getService().getSession();
+ if (session.isTalking() && !mSettings.isPushToTalkToggle()) {
+ session.setTalkingState(false);
+ }
}
}
@@ -290,8 +289,7 @@ public class PlumbleActivity extends ActionBarActivity implements ListView.OnIte
dadb.setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
- if(mService != null && mService.isConnectionEstablished())
- mService.disconnect();
+ if(mService != null) mService.disconnect();
loadDrawerFragment(DrawerAdapter.ITEM_FAVOURITES);
}
});
@@ -372,7 +370,7 @@ public class PlumbleActivity extends ActionBarActivity implements ListView.OnIte
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
MenuItem disconnectButton = menu.findItem(R.id.action_disconnect);
- disconnectButton.setVisible(mService != null && mService.isSynchronized());
+ disconnectButton.setVisible(mService != null && mService.isConnected());
// Color the action bar icons to the primary text color of the theme.
int foregroundColor = getSupportActionBar().getThemedContext()
@@ -436,7 +434,7 @@ public class PlumbleActivity extends ActionBarActivity implements ListView.OnIte
@Override
public void onBackPressed() {
- if(mService != null && mService.isSynchronized()) {
+ if(mService != null && mService.isConnected()) {
mDisconnectPromptBuilder.show();
return;
}
@@ -495,8 +493,9 @@ public class PlumbleActivity extends ActionBarActivity implements ListView.OnIte
break;
case DrawerAdapter.ITEM_ACCESS_TOKENS:
fragmentClass = AccessTokenFragment.class;
- args.putLong("server", mService.getConnectedServer().getId());
- args.putStringArrayList("access_tokens", (ArrayList<String>) mDatabase.getAccessTokens(mService.getConnectedServer().getId()));
+ Server connectedServer = getService().getTargetServer();
+ args.putLong("server", connectedServer.getId());
+ args.putStringArrayList("access_tokens", (ArrayList<String>) mDatabase.getAccessTokens(connectedServer.getId()));
break;
case DrawerAdapter.ITEM_PINNED_CHANNELS:
fragmentClass = ChannelFragment.class;
@@ -525,7 +524,7 @@ public class PlumbleActivity extends ActionBarActivity implements ListView.OnIte
public void connectToServer(final Server server) {
// Check if we're already connected to a server; if so, inform user.
- if(mService != null && mService.isConnectionEstablished()) {
+ if(mService != null && mService.isConnected()) {
AlertDialog.Builder adb = new AlertDialog.Builder(this);
adb.setMessage(R.string.reconnect_dialog_message);
adb.setPositiveButton(R.string.connect, new DialogInterface.OnClickListener() {
@@ -610,7 +609,7 @@ public class PlumbleActivity extends ActionBarActivity implements ListView.OnIte
switch (mService.getConnectionState()) {
case CONNECTING:
- Server server = service.getConnectedServer();
+ Server server = service.getTargetServer();
mConnectingDialog = new ProgressDialog(this);
mConnectingDialog.setIndeterminate(true);
mConnectingDialog.setCancelable(true);
@@ -657,7 +656,7 @@ public class PlumbleActivity extends ActionBarActivity implements ListView.OnIte
ab.setPositiveButton(R.string.reconnect, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
- Server server = getService().getConnectedServer();
+ Server server = getService().getTargetServer();
if (server == null)
return;
String password = passwordField.getText().toString();
@@ -698,7 +697,7 @@ public class PlumbleActivity extends ActionBarActivity implements ListView.OnIte
*/
@Override
- public PlumbleService getService() {
+ public IPlumbleService getService() {
return mService;
}
@@ -738,13 +737,13 @@ public class PlumbleActivity extends ActionBarActivity implements ListView.OnIte
@Override
public boolean isConnected() {
- return mService != null && mService.isSynchronized();
+ return mService != null && mService.isConnected();
}
@Override
public String getConnectedServerName() {
- if(mService != null && mService.isSynchronized()) {
- Server server = mService.getConnectedServer();
+ if(mService != null && mService.isConnected()) {
+ Server server = mService.getTargetServer();
return server.getName().equals("") ? server.getHost() : server.getName();
}
if (BuildConfig.DEBUG)
diff --git a/app/src/main/java/com/morlunk/mumbleclient/channel/AccessTokenFragment.java b/app/src/main/java/com/morlunk/mumbleclient/channel/AccessTokenFragment.java
index bb6efe5..80fd0bf 100644
--- a/app/src/main/java/com/morlunk/mumbleclient/channel/AccessTokenFragment.java
+++ b/app/src/main/java/com/morlunk/mumbleclient/channel/AccessTokenFragment.java
@@ -120,7 +120,9 @@ public class AccessTokenFragment extends JumbleServiceFragment {
mTokenList.smoothScrollToPosition(mTokens.size() - 1);
mProvider.getDatabase().addAccessToken(getServerId(), tokenText);
- getService().sendAccessTokens(mTokens);
+ if (getService().isConnected()) {
+ getService().getSession().sendAccessTokens(mTokens);
+ }
}
private long getServerId() {
@@ -158,7 +160,9 @@ public class AccessTokenFragment extends JumbleServiceFragment {
mTokens.remove(position);
notifyDataSetChanged();
mProvider.getDatabase().removeAccessToken(getServerId(), token);
- getService().sendAccessTokens(mTokens);
+ if (getService().isConnected()) {
+ getService().getSession().sendAccessTokens(mTokens);
+ }
}
});
diff --git a/app/src/main/java/com/morlunk/mumbleclient/channel/ChannelChatFragment.java b/app/src/main/java/com/morlunk/mumbleclient/channel/ChannelChatFragment.java
index 0a0d613..0d99897 100644
--- a/app/src/main/java/com/morlunk/mumbleclient/channel/ChannelChatFragment.java
+++ b/app/src/main/java/com/morlunk/mumbleclient/channel/ChannelChatFragment.java
@@ -43,18 +43,16 @@ import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import com.morlunk.jumble.IJumbleService;
-import com.morlunk.jumble.JumbleService;
-import com.morlunk.jumble.model.Channel;
+import com.morlunk.jumble.IJumbleSession;
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 com.morlunk.jumble.util.IJumbleObserver;
+import com.morlunk.jumble.util.JumbleDisconnectedException;
import com.morlunk.jumble.util.JumbleObserver;
import com.morlunk.mumbleclient.R;
import com.morlunk.mumbleclient.service.IChatMessage;
-import com.morlunk.mumbleclient.service.PlumbleService;
import com.morlunk.mumbleclient.util.JumbleServiceFragment;
import com.morlunk.mumbleclient.util.MumbleImageGetter;
@@ -63,7 +61,6 @@ import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
-import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -94,11 +91,15 @@ public class ChannelChatFragment extends JumbleServiceFragment implements ChatTa
@Override
public void onUserJoinedChannel(IUser user, IChannel newChannel, IChannel oldChannel) {
- if (user != null && getService().getSessionUser() != null &&
- user.equals(getService().getSessionUser()) &&
- mTargetProvider.getChatTarget() == null) {
- // Update chat target when user changes channels without a target.
- updateChatTargetText(null);
+ IJumbleService service = getService();
+ if (service.isConnected()) {
+ IJumbleSession session = service.getSession();
+ if (user != null && session.getSessionUser() != null &&
+ user.equals(session.getSessionUser()) &&
+ mTargetProvider.getChatTarget() == null) {
+ // Update chat target when user changes channels without a target.
+ updateChatTargetText(null);
+ }
}
}
};
@@ -148,22 +149,14 @@ public class ChannelChatFragment extends JumbleServiceFragment implements ChatTa
mSendButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
- try {
- sendMessage();
- } catch (RemoteException e) {
- e.printStackTrace();
- }
+ sendMessage();
}
});
mChatTextEdit.setOnEditorActionListener(new OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
- try {
- sendMessage();
- } catch (RemoteException e) {
- e.printStackTrace();
- }
+ sendMessage();
return true;
}
});
@@ -228,20 +221,21 @@ public class ChannelChatFragment extends JumbleServiceFragment implements ChatTa
/**
* Sends the message currently in {@link com.morlunk.mumbleclient.channel.ChannelChatFragment#mChatTextEdit}
* to the remote server. Clears the message box if the message was sent successfully.
- * @throws RemoteException If the service failed to send the message.
+ * @throws JumbleDisconnectedException If the service is disconnected.
*/
- private void sendMessage() throws RemoteException {
+ private void sendMessage() throws JumbleDisconnectedException {
if(mChatTextEdit.length() == 0) return;
String message = mChatTextEdit.getText().toString();
String formattedMessage = markupOutgoingMessage(message);
ChatTargetProvider.ChatTarget target = mTargetProvider.getChatTarget();
IMessage responseMessage = null;
+ IJumbleSession session = getService().getSession();
if(target == null)
- responseMessage = getService().sendChannelTextMessage(getService().getSessionChannel().getId(), formattedMessage, false);
+ responseMessage = session.sendChannelTextMessage(session.getSessionChannel().getId(), formattedMessage, false);
else if(target.getUser() != null)
- responseMessage = getService().sendUserTextMessage(target.getUser().getSession(), formattedMessage);
+ responseMessage = session.sendUserTextMessage(target.getUser().getSession(), formattedMessage);
else if(target.getChannel() != null)
- responseMessage = getService().sendChannelTextMessage(target.getChannel().getId(), formattedMessage, false);
+ responseMessage = session.sendChannelTextMessage(target.getChannel().getId(), formattedMessage, false);
addChatMessage(new IChatMessage.TextMessage(responseMessage), true);
mChatTextEdit.setText("");
}
@@ -267,12 +261,13 @@ public class ChannelChatFragment extends JumbleServiceFragment implements ChatTa
/**
* Updates hint displaying chat target.
*/
- public void updateChatTargetText(ChatTargetProvider.ChatTarget target) {
- if(getService() == null) return;
+ public void updateChatTargetText(final ChatTargetProvider.ChatTarget target) {
+ if(getService() == null || !getService().isConnected()) return;
+ IJumbleSession session = getService().getSession();
String hint = null;
- if(target == null && getService().getSessionChannel() != null) {
- hint = getString(R.string.messageToChannel, getService().getSessionChannel().getName());
+ if(target == null && session.getSessionChannel() != null) {
+ hint = getString(R.string.messageToChannel, session.getSessionChannel().getName());
} else if(target != null && target.getUser() != null) {
hint = getString(R.string.messageToUser, target.getUser().getName());
} else if(target != null && target.getChannel() != null) {
@@ -335,8 +330,12 @@ public class ChannelChatFragment extends JumbleServiceFragment implements ChatTa
public void visit(IChatMessage.TextMessage message) {
IMessage textMessage = message.getMessage();
String targetMessage = getContext().getString(R.string.unknown);
- boolean selfAuthored = mService.getConnectionState() == JumbleService.ConnectionState.CONNECTED &&
- textMessage.getActor() == mService.getSession();
+ boolean selfAuthored;
+ try {
+ selfAuthored = textMessage.getActor() == mService.getSession().getSessionId();
+ } catch (JumbleDisconnectedException e) {
+ selfAuthored = false;
+ }
if (textMessage.getTargetChannels() != null && !textMessage.getTargetChannels().isEmpty()) {
IChannel currentChannel = (IChannel) textMessage.getTargetChannels().get(0);
diff --git a/app/src/main/java/com/morlunk/mumbleclient/channel/ChannelEditFragment.java b/app/src/main/java/com/morlunk/mumbleclient/channel/ChannelEditFragment.java
index 6004c24..548a593 100644
--- a/app/src/main/java/com/morlunk/mumbleclient/channel/ChannelEditFragment.java
+++ b/app/src/main/java/com/morlunk/mumbleclient/channel/ChannelEditFragment.java
@@ -29,6 +29,7 @@ import android.view.View;
import android.widget.CheckBox;
import android.widget.TextView;
+import com.morlunk.jumble.IJumbleSession;
import com.morlunk.jumble.model.Channel;
import com.morlunk.jumble.model.IChannel;
import com.morlunk.jumble.net.Permissions;
@@ -67,13 +68,17 @@ public class ChannelEditFragment extends DialogFragment {
mTemporaryBox = (CheckBox) view.findViewById(R.id.channel_edit_temporary);
// If we can only make temporary channels, remove the option.
- IChannel parentChannel = mServiceProvider.getService().getChannel(getParent());
- int combinedPermissions = mServiceProvider.getService().getPermissions() | parentChannel.getPermissions();
- boolean canMakeChannel = (combinedPermissions & Permissions.MakeChannel) > 0;
- boolean canMakeTempChannel = (combinedPermissions & Permissions.MakeTempChannel) > 0;
- boolean onlyTemp = canMakeTempChannel && !canMakeChannel;
- mTemporaryBox.setChecked(onlyTemp);
- mTemporaryBox.setEnabled(!onlyTemp);
+ if (mServiceProvider.getService().isConnected()) {
+ // TODO: we probably should just stop this dialog in its tracks if we're disconnected.
+ IJumbleSession session = mServiceProvider.getService().getSession();
+ IChannel parentChannel = session.getChannel(getParent());
+ int combinedPermissions = session.getPermissions() | parentChannel.getPermissions();
+ boolean canMakeChannel = (combinedPermissions & Permissions.MakeChannel) > 0;
+ boolean canMakeTempChannel = (combinedPermissions & Permissions.MakeTempChannel) > 0;
+ boolean onlyTemp = canMakeTempChannel && !canMakeChannel;
+ mTemporaryBox.setChecked(onlyTemp);
+ mTemporaryBox.setEnabled(!onlyTemp);
+ }
return new AlertDialog.Builder(getActivity())
.setTitle(isAdding() ? R.string.channel_add : R.string.channel_edit)
@@ -81,8 +86,8 @@ public class ChannelEditFragment extends DialogFragment {
.setPositiveButton(isAdding() ? R.string.add : R.string.save, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
- if(isAdding()) {
- mServiceProvider.getService().createChannel(getParent(),
+ if(isAdding() && mServiceProvider.getService().isConnected()) {
+ mServiceProvider.getService().getSession().createChannel(getParent(),
mNameField.getText().toString(),
mDescriptionField.getText().toString(),
Integer.parseInt(mPositionField.getText().toString()), // We can guarantee this to be an int. InputType is numberSigned.
diff --git a/app/src/main/java/com/morlunk/mumbleclient/channel/ChannelFragment.java b/app/src/main/java/com/morlunk/mumbleclient/channel/ChannelFragment.java
index 3c8e56d..bc2932c 100644
--- a/app/src/main/java/com/morlunk/mumbleclient/channel/ChannelFragment.java
+++ b/app/src/main/java/com/morlunk/mumbleclient/channel/ChannelFragment.java
@@ -21,7 +21,6 @@ import android.animation.Animator;
import android.content.SharedPreferences;
import android.content.res.TypedArray;
import android.os.Bundle;
-import android.os.RemoteException;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
@@ -36,19 +35,14 @@ import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
-import android.view.animation.Animation;
-import android.view.animation.AnimationSet;
-import android.view.animation.AnimationUtils;
import android.widget.Button;
-import android.widget.CheckBox;
import android.widget.ImageView;
-import android.widget.LinearLayout;
import android.widget.TextView;
import com.morlunk.jumble.IJumbleService;
+import com.morlunk.jumble.IJumbleSession;
import com.morlunk.jumble.JumbleService;
import com.morlunk.jumble.model.IUser;
-import com.morlunk.jumble.model.User;
import com.morlunk.jumble.model.WhisperTarget;
import com.morlunk.jumble.util.IJumbleObserver;
import com.morlunk.jumble.util.JumbleObserver;
@@ -85,26 +79,32 @@ public class ChannelFragment extends JumbleServiceFragment implements SharedPref
private JumbleObserver mObserver = new JumbleObserver() {
@Override
public void onUserTalkStateUpdated(IUser user) {
- if (user != null && user.getSession() == getService().getSession()) {
- // Manually set button selection colour when we receive a talk state update.
- // This allows representation of talk state when using hot corners and PTT toggle.
- switch (user.getTalkState()) {
- case TALKING:
- case SHOUTING:
- case WHISPERING:
- mTalkButton.setPressed(true);
- break;
- case PASSIVE:
- mTalkButton.setPressed(false);
- break;
+ if (getService().isConnected()) {
+ IJumbleSession session = getService().getSession();
+ if (user != null && user.getSession() == session.getSessionId()) {
+ // Manually set button selection colour when we receive a talk state update.
+ // This allows representation of talk state when using hot corners and PTT toggle.
+ switch (user.getTalkState()) {
+ case TALKING:
+ case SHOUTING:
+ case WHISPERING:
+ mTalkButton.setPressed(true);
+ break;
+ case PASSIVE:
+ mTalkButton.setPressed(false);
+ break;
+ }
}
}
}
@Override
public void onUserStateUpdated(IUser user) {
- if (user != null && user.getSession() == getService().getSession()) {
- configureInput();
+ if (getService().isConnected()) {
+ IJumbleSession session = getService().getSession();
+ if (user != null && user.getSession() == session.getSessionId()) {
+ configureInput();
+ }
}
}
@@ -160,12 +160,14 @@ public class ChannelFragment extends JumbleServiceFragment implements SharedPref
mTargetPanelCancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- if (getService() != null &&
- getService().getConnectionState() == JumbleService.ConnectionState.CONNECTED &&
- getService().getVoiceTargetMode() == VoiceTargetMode.WHISPER) {
- byte target = getService().getVoiceTargetId();
- getService().setVoiceTargetId((byte) 0);
- getService().unregisterWhisperTarget(target);
+ if (getService() == null || !getService().isConnected())
+ return;
+
+ IJumbleSession session = getService().getSession();
+ if (session.getVoiceTargetMode() == VoiceTargetMode.WHISPER) {
+ byte target = session.getVoiceTargetId();
+ session.setVoiceTargetId((byte) 0);
+ session.unregisterWhisperTarget(target);
}
}
});
@@ -224,10 +226,11 @@ public class ChannelFragment extends JumbleServiceFragment implements SharedPref
@Override
public void onPause() {
super.onPause();
- if (getService() != null && !Settings.getInstance(getActivity()).isPushToTalkToggle()) {
+ if (getService() != null && getService().isConnected() &&
+ !Settings.getInstance(getActivity()).isPushToTalkToggle()) {
// XXX: This ensures that push to talk is disabled when we pause.
// We don't want to leave the talk state active if the fragment is paused while pressed.
- getService().setTalkingState(false);
+ getService().getSession().setTalkingState(false);
}
}
@@ -253,9 +256,13 @@ public class ChannelFragment extends JumbleServiceFragment implements SharedPref
}
private void configureTargetPanel() {
- VoiceTargetMode mode = getService().getVoiceTargetMode();
+ if (!getService().isConnected())
+ return;
+
+ IJumbleSession session = getService().getSession();
+ VoiceTargetMode mode = session.getVoiceTargetMode();
if (mode == VoiceTargetMode.WHISPER) {
- WhisperTarget target = getService().getWhisperTarget();
+ WhisperTarget target = session.getWhisperTarget();
mTargetPanel.setVisibility(View.VISIBLE);
mTargetPanelText.setText(getString(R.string.shout_target, target.getName()));
} else {
@@ -282,8 +289,8 @@ public class ChannelFragment extends JumbleServiceFragment implements SharedPref
mTalkButton.setLayoutParams(params);
boolean muted = false;
- if (getService().getConnectionState() == JumbleService.ConnectionState.CONNECTED) {
- IUser user = getService().getSessionUser();
+ if (getService().isConnected()) {
+ IUser user = getService().getSession().getSessionUser();
muted = user.isMuted() || user.isSuppressed() || user.isSelfMuted();
}
boolean showPttButton =
diff --git a/app/src/main/java/com/morlunk/mumbleclient/channel/ChannelListAdapter.java b/app/src/main/java/com/morlunk/mumbleclient/channel/ChannelListAdapter.java
index 2b3f233..bf649af 100644
--- a/app/src/main/java/com/morlunk/mumbleclient/channel/ChannelListAdapter.java
+++ b/app/src/main/java/com/morlunk/mumbleclient/channel/ChannelListAdapter.java
@@ -17,39 +17,31 @@
package com.morlunk.mumbleclient.channel;
-import android.animation.AnimatorInflater;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
-import android.os.Build;
import android.os.RemoteException;
import android.support.v4.app.FragmentManager;
import android.support.v7.widget.RecyclerView;
import android.util.DisplayMetrics;
-import android.util.Log;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.view.animation.Animation;
-import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.LinearLayout;
-import android.widget.ProgressBar;
import android.widget.TextView;
import com.morlunk.jumble.IJumbleService;
+import com.morlunk.jumble.IJumbleSession;
import com.morlunk.jumble.JumbleService;
import com.morlunk.jumble.model.IChannel;
import com.morlunk.jumble.model.IUser;
import com.morlunk.jumble.model.Server;
import com.morlunk.jumble.model.TalkState;
-import com.morlunk.mumbleclient.Constants;
import com.morlunk.mumbleclient.R;
import com.morlunk.mumbleclient.db.PlumbleDatabase;
import com.morlunk.mumbleclient.drawable.CircleDrawable;
@@ -102,7 +94,7 @@ public class ChannelListAdapter extends RecyclerView.Adapter implements UserMenu
mRootChannels = new ArrayList<Integer>();
if(showPinnedOnly) {
- mRootChannels = mDatabase.getPinnedChannels(mService.getConnectedServer().getId());
+ mRootChannels = mDatabase.getPinnedChannels(mService.getTargetServer().getId());
} else {
mRootChannels.add(0);
}
@@ -161,9 +153,9 @@ public class ChannelListAdapter extends RecyclerView.Adapter implements UserMenu
cvh.mChannelName.setText(channel.getName());
int nameTypeface = Typeface.NORMAL;
- if (mService != null &&
- mService.getConnectionState() == JumbleService.ConnectionState.CONNECTED) {
- if (channel.equals(mService.getSessionChannel())) {
+ if (mService != null && mService.isConnected()) {
+ IJumbleSession session = mService.getSession();
+ if (channel.equals(session.getSessionChannel())) {
nameTypeface |= Typeface.BOLD;
// Always italicize our current channel if it has a link.
if (channel.getLinks().size() > 0) {
@@ -171,7 +163,7 @@ public class ChannelListAdapter extends RecyclerView.Adapter implements UserMenu
}
}
// Italicize channels in a link with our current channel.
- if (channel.getLinks().contains(mService.getSessionChannel())) {
+ if (channel.getLinks().contains(session.getSessionChannel())) {
nameTypeface |= Typeface.ITALIC;
}
}
@@ -196,7 +188,8 @@ public class ChannelListAdapter extends RecyclerView.Adapter implements UserMenu
cvh.mJoinButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- mService.joinChannel(channel.getId());
+ if (mService.isConnected())
+ mService.getSession().joinChannel(channel.getId());
}
});
@@ -228,7 +221,14 @@ public class ChannelListAdapter extends RecyclerView.Adapter implements UserMenu
});
uvh.mUserName.setText(user.getName());
- uvh.mUserName.setTypeface(null, user.getSession() == mService.getSession() ? Typeface.BOLD : Typeface.NORMAL);
+
+ final int typefaceStyle;
+ if (mService.isConnected() && mService.getSession().getSessionId() == user.getSession()) {
+ typefaceStyle = Typeface.BOLD;
+ } else {
+ typefaceStyle = Typeface.NORMAL;
+ }
+ uvh.mUserName.setTypeface(null, typefaceStyle);
uvh.mUserTalkHighlight.setImageDrawable(getTalkStateDrawable(user));
uvh.mTalkingIndicator.setAlpha(
@@ -293,12 +293,15 @@ public class ChannelListAdapter extends RecyclerView.Adapter implements UserMenu
/**
* Updates the channel tree model.
* To be used after any channel tree modifications.
- * @throws IllegalStateException if the service is not synchronized when calling this.
*/
public void updateChannels() {
+ if (!mService.isConnected())
+ return;
+
+ IJumbleSession session = mService.getSession();
mNodes.clear();
for (int cid : mRootChannels) {
- IChannel channel = mService.getChannel(cid);
+ IChannel channel = session.getChannel(cid);
if (channel != null) {
constructNodes(null, channel, 0, mNodes);
}
@@ -469,7 +472,7 @@ public class ChannelListAdapter extends RecyclerView.Adapter implements UserMenu
notifyDataSetChanged();
// Add or remove registered user from local mute history
- final Server server = mService.getConnectedServer();
+ final Server server = mService.getTargetServer();
if (user.getUserId() >= 0 && server.isSaved()) {
new Thread(new Runnable() {
diff --git a/app/src/main/java/com/morlunk/mumbleclient/channel/ChannelListFragment.java b/app/src/main/java/com/morlunk/mumbleclient/channel/ChannelListFragment.java
index 3427509..fb234a4 100644
--- a/app/src/main/java/com/morlunk/mumbleclient/channel/ChannelListFragment.java
+++ b/app/src/main/java/com/morlunk/mumbleclient/channel/ChannelListFragment.java
@@ -44,6 +44,7 @@ import android.view.View;
import android.view.ViewGroup;
import com.morlunk.jumble.IJumbleService;
+import com.morlunk.jumble.IJumbleSession;
import com.morlunk.jumble.model.IChannel;
import com.morlunk.jumble.model.IUser;
import com.morlunk.jumble.util.IJumbleObserver;
@@ -66,7 +67,8 @@ public class ChannelListFragment extends JumbleServiceFragment implements OnChan
public void onUserJoinedChannel(IUser user, IChannel newChannel, IChannel oldChannel) {
mChannelListAdapter.updateChannels();
mChannelListAdapter.notifyDataSetChanged();
- if(getService().getSession() == user.getSession()) {
+ if(getService().isConnected() &&
+ getService().getSession().getSessionId() == user.getSession()) {
scrollToChannel(newChannel.getId());
}
}
@@ -99,7 +101,7 @@ public class ChannelListFragment extends JumbleServiceFragment implements OnChan
public void onUserRemoved(IUser user, String reason) {
// If we are the user being removed, don't update the channel list.
// We won't be in a synchronized state.
- if (!getService().isSynchronized())
+ if (!getService().isConnected())
return;
mChannelListAdapter.updateChannels();
@@ -212,19 +214,20 @@ public class ChannelListFragment extends JumbleServiceFragment implements OnChan
MenuItem muteItem = menu.findItem(R.id.menu_mute_button);
MenuItem deafenItem = menu.findItem(R.id.menu_deafen_button);
- if(getService() != null
- && getService().isSynchronized()) {
+ if(getService() != null && getService().isConnected()) {
+ IJumbleSession session = getService().getSession();
+
// Color the action bar icons to the primary text color of the theme, TODO move this elsewhere
int foregroundColor = getActivity().getTheme().obtainStyledAttributes(new int[]{android.R.attr.textColorPrimaryInverse}).getColor(0, -1);
- IUser self = getService().getSessionUser();
+ IUser self = session.getSessionUser();
muteItem.setIcon(self.isSelfMuted() ? R.drawable.ic_action_microphone_muted : R.drawable.ic_action_microphone);
deafenItem.setIcon(self.isSelfDeafened() ? R.drawable.ic_action_audio_muted : R.drawable.ic_action_audio);
muteItem.getIcon().mutate().setColorFilter(foregroundColor, PorterDuff.Mode.MULTIPLY);
deafenItem.getIcon().mutate().setColorFilter(foregroundColor, PorterDuff.Mode.MULTIPLY);
MenuItem bluetoothItem = menu.findItem(R.id.menu_bluetooth);
- bluetoothItem.setChecked(getService().usingBluetoothSco());
+ bluetoothItem.setChecked(session.usingBluetoothSco());
}
}
@@ -245,14 +248,18 @@ public class ChannelListFragment extends JumbleServiceFragment implements OnChan
@Override
public boolean onSuggestionClick(int i) {
+ if (getService() == null || !getService().isConnected())
+ return false;
CursorWrapper cursor = (CursorWrapper) searchView.getSuggestionsAdapter().getItem(i);
int typeColumn = cursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA);
int dataIdColumn = cursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_INTENT_DATA);
String itemType = cursor.getString(typeColumn);
int itemId = cursor.getInt(dataIdColumn);
+
+ IJumbleSession session = getService().getSession();
if(ChannelSearchProvider.INTENT_DATA_CHANNEL.equals(itemType)) {
- if(getService().getSessionChannel().getId() != itemId) {
- getService().joinChannel(itemId);
+ if(session.getSessionChannel().getId() != itemId) {
+ session.joinChannel(itemId);
} else {
scrollToChannel(itemId);
}
@@ -268,24 +275,27 @@ public class ChannelListFragment extends JumbleServiceFragment implements OnChan
@Override
public boolean onOptionsItemSelected(MenuItem item) {
+ if (getService() == null || !getService().isConnected())
+ return super.onOptionsItemSelected(item);
+ IJumbleSession session = getService().getSession();
switch (item.getItemId()) {
case R.id.menu_mute_button: {
- IUser self = getService().getSessionUser();
+ IUser self = session.getSessionUser();
boolean muted = !self.isSelfMuted();
boolean deafened = self.isSelfDeafened();
deafened &= muted; // Undeafen if mute is off
- getService().setSelfMuteDeafState(muted, deafened);
+ session.setSelfMuteDeafState(muted, deafened);
getActivity().supportInvalidateOptionsMenu();
return true;
}
case R.id.menu_deafen_button: {
- IUser self = getService().getSessionUser();
+ IUser self = session.getSessionUser();
boolean deafened = !self.isSelfDeafened();
- getService().setSelfMuteDeafState(deafened, deafened);
+ session.setSelfMuteDeafState(deafened, deafened);
getActivity().supportInvalidateOptionsMenu();
return true;
@@ -295,9 +305,9 @@ public class ChannelListFragment extends JumbleServiceFragment implements OnChan
case R.id.menu_bluetooth:
item.setChecked(!item.isChecked());
if (item.isChecked()) {
- getService().enableBluetoothSco();
+ session.enableBluetoothSco();
} else {
- getService().disableBluetoothSco();
+ session.disableBluetoothSco();
}
return true;
}
diff --git a/app/src/main/java/com/morlunk/mumbleclient/channel/ChannelMenu.java b/app/src/main/java/com/morlunk/mumbleclient/channel/ChannelMenu.java
index 3044a6b..cca5866 100644
--- a/app/src/main/java/com/morlunk/mumbleclient/channel/ChannelMenu.java
+++ b/app/src/main/java/com/morlunk/mumbleclient/channel/ChannelMenu.java
@@ -35,6 +35,7 @@ import android.widget.LinearLayout;
import android.widget.Toast;
import com.morlunk.jumble.IJumbleService;
+import com.morlunk.jumble.IJumbleSession;
import com.morlunk.jumble.JumbleService;
import com.morlunk.jumble.model.IChannel;
import com.morlunk.jumble.model.Server;
@@ -74,21 +75,26 @@ public class ChannelMenu implements PermissionsPopupMenu.IOnMenuPrepareListener,
menu.findItem(R.id.context_channel_view_description)
.setVisible(mChannel.getDescription() != null ||
mChannel.getDescriptionHash() != null);
- Server server = mService.getConnectedServer();
+ Server server = mService.getTargetServer();
if(server != null) {
menu.findItem(R.id.context_channel_pin)
.setChecked(mDatabase.isChannelPinned(server.getId(), mChannel.getId()));
}
- menu.findItem(R.id.context_channel_link)
- .setChecked(mChannel.getLinks().contains(mService.getSessionChannel()));
+ if (mService.isConnected()) {
+ menu.findItem(R.id.context_channel_link)
+ .setChecked(mChannel.getLinks().contains(mService.getSession().getSessionChannel()));
+ }
}
@Override
public boolean onMenuItemClick(MenuItem item) {
+ if (!mService.isConnected())
+ return false;
+
boolean adding = false;
switch(item.getItemId()) {
case R.id.context_channel_join:
- mService.joinChannel(mChannel.getId());
+ mService.getSession().joinChannel(mChannel.getId());
break;
case R.id.context_channel_add:
adding = true;
@@ -108,7 +114,9 @@ public class ChannelMenu implements PermissionsPopupMenu.IOnMenuPrepareListener,
adb.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
- mService.removeChannel(mChannel.getId());
+ if (mService.isConnected()) {
+ mService.getSession().removeChannel(mChannel.getId());
+ }
}
});
adb.setNegativeButton(android.R.string.cancel, null);
@@ -124,22 +132,22 @@ public class ChannelMenu implements PermissionsPopupMenu.IOnMenuPrepareListener,
commentFragment.show(mFragmentManager, ChannelDescriptionFragment.class.getName());
break;
case R.id.context_channel_pin:
- long serverId = mService.getConnectedServer().getId();
+ long serverId = mService.getTargetServer().getId();
boolean pinned = mDatabase.isChannelPinned(serverId, mChannel.getId());
if(!pinned) mDatabase.addPinnedChannel(serverId, mChannel.getId());
else mDatabase.removePinnedChannel(serverId, mChannel.getId());
break;
case R.id.context_channel_link: {
- IChannel channel = mService.getSessionChannel();
+ IChannel channel = mService.getSession().getSessionChannel();
if (!item.isChecked()) {
- mService.linkChannels(channel, mChannel);
+ mService.getSession().linkChannels(channel, mChannel);
} else {
- mService.unlinkChannels(channel, mChannel);
+ mService.getSession().unlinkChannels(channel, mChannel);
}
break;
}
case R.id.context_channel_unlink_all:
- mService.unlinkAllChannels(mChannel);
+ mService.getSession().unlinkAllChannels(mChannel);
break;
case R.id.context_channel_shout: {
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
@@ -159,20 +167,21 @@ public class ChannelMenu implements PermissionsPopupMenu.IOnMenuPrepareListener,
builder.setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
- if (mService == null ||
- mService.getConnectionState() != JumbleService.ConnectionState.CONNECTED)
+ if (!mService.isConnected())
return;
+ IJumbleSession session = mService.getSession();
+
// Unregister any existing voice target.
- if (mService.getVoiceTargetMode() == VoiceTargetMode.WHISPER) {
- mService.unregisterWhisperTarget(mService.getVoiceTargetId());
+ if (session.getVoiceTargetMode() == VoiceTargetMode.WHISPER) {
+ session.unregisterWhisperTarget(session.getVoiceTargetId());
}
WhisperTargetChannel channelTarget = new WhisperTargetChannel(mChannel,
linkedBox.isChecked(), subchannelBox.isChecked(), null);
- byte id = mService.registerWhisperTarget(channelTarget);
+ byte id = session.registerWhisperTarget(channelTarget);
if (id > 0) {
- mService.setVoiceTargetId(id);
+ session.setVoiceTargetId(id);
} else {
Toast.makeText(mContext, R.string.shout_failed, Toast.LENGTH_LONG).show();
}
diff --git a/app/src/main/java/com/morlunk/mumbleclient/channel/ChannelSearchProvider.java b/app/src/main/java/com/morlunk/mumbleclient/channel/ChannelSearchProvider.java
index a713f82..30f1740 100644
--- a/app/src/main/java/com/morlunk/mumbleclient/channel/ChannelSearchProvider.java
+++ b/app/src/main/java/com/morlunk/mumbleclient/channel/ChannelSearchProvider.java
@@ -31,6 +31,7 @@ import android.os.RemoteException;
import android.util.Log;
import com.morlunk.jumble.IJumbleService;
+import com.morlunk.jumble.IJumbleSession;
import com.morlunk.jumble.JumbleService;
import com.morlunk.jumble.model.Channel;
import com.morlunk.jumble.model.IChannel;
@@ -55,7 +56,7 @@ public class ChannelSearchProvider extends ContentProvider {
private ServiceConnection mConn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
- mService = ((JumbleService.JumbleBinder) service).getService();
+ mService = ((PlumbleService.PlumbleBinder) service).getService();
synchronized (mServiceLock) {
mServiceLock.notify();
}
@@ -113,6 +114,11 @@ public class ChannelSearchProvider extends ContentProvider {
}
}
}
+
+ if (!mService.isConnected())
+ return null;
+
+ IJumbleSession session = mService.getSession();
String query = "";
for(int x=0;x<selectionArgs.length;x++) {
@@ -125,23 +131,17 @@ public class ChannelSearchProvider extends ContentProvider {
MatrixCursor cursor = new MatrixCursor(new String[] { "_ID", SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA, SearchManager.SUGGEST_COLUMN_TEXT_1, SearchManager.SUGGEST_COLUMN_ICON_1, SearchManager.SUGGEST_COLUMN_TEXT_2, SearchManager.SUGGEST_COLUMN_INTENT_DATA });
- List<IChannel> channels;
- List<IUser> users;
- try {
- channels = channelSearch(mService.getRootChannel(), query);
- users = userSearch(mService.getRootChannel(), query);
+ List<IChannel> channels = channelSearch(session.getRootChannel(), query);
+ List<IUser> users = userSearch(session.getRootChannel(), query);
- for(int x=0;x<channels.size();x++) {
- IChannel channel = channels.get(x);
- cursor.addRow(new Object[] { x, INTENT_DATA_CHANNEL, channel.getName(), R.drawable.ic_action_channels, getContext().getString(R.string.search_channel_users, channel.getSubchannelUserCount()), channel.getId() });
- }
+ for(int x=0;x<channels.size();x++) {
+ IChannel channel = channels.get(x);
+ cursor.addRow(new Object[] { x, INTENT_DATA_CHANNEL, channel.getName(), R.drawable.ic_action_channels, getContext().getString(R.string.search_channel_users, channel.getSubchannelUserCount()), channel.getId() });
+ }
- for(int x=0;x<users.size();x++) {
- IUser user = users.get(x);
- cursor.addRow(new Object[] { x, INTENT_DATA_USER, user.getName(), R.drawable.ic_action_user_dark, getContext().getString(R.string.user), user.getSession() });
- }
- } catch (RemoteException e) {
- e.printStackTrace();
+ for(int x=0;x<users.size();x++) {
+ IUser user = users.get(x);
+ cursor.addRow(new Object[] { x, INTENT_DATA_USER, user.getName(), R.drawable.ic_action_user_dark, getContext().getString(R.string.user), user.getSession() });
}
return cursor;
}
@@ -153,7 +153,7 @@ public class ChannelSearchProvider extends ContentProvider {
* @param str The string to match against the user's name. Case insensitive.
* @return A list of users whose names contain str.
*/
- private List<IUser> userSearch(IChannel root, String str) throws RemoteException {
+ private List<IUser> userSearch(IChannel root, String str) {
List<IUser> list = new LinkedList<IUser>();
userSearch(root, str, list);
return list;
@@ -162,7 +162,7 @@ public class ChannelSearchProvider extends ContentProvider {
/**
* @see #userSearch(IChannel,String)
*/
- private void userSearch(IChannel root, String str, List<IUser> users) throws RemoteException {
+ private void userSearch(IChannel root, String str, List<IUser> users) {
if (root == null) {
return;
}
@@ -185,7 +185,7 @@ public class ChannelSearchProvider extends ContentProvider {
* @param str The string to match against the channel's name. Case insensitive.
* @return A list of channels whose names contain str.
*/
- private List<IChannel> channelSearch(IChannel root, String str) throws RemoteException {
+ private List<IChannel> channelSearch(IChannel root, String str) {
List<IChannel> list = new LinkedList<IChannel>();
channelSearch(root, str, list);
return list;
@@ -194,7 +194,7 @@ public class ChannelSearchProvider extends ContentProvider {
/**
* @see #channelSearch(IChannel,String)
*/
- private void channelSearch(IChannel root, String str, List<IChannel> channels) throws RemoteException {
+ private void channelSearch(IChannel root, String str, List<IChannel> channels) {
if (root == null) {
return;
}
diff --git a/app/src/main/java/com/morlunk/mumbleclient/channel/PermissionsPopupMenu.java b/app/src/main/java/com/morlunk/mumbleclient/channel/PermissionsPopupMenu.java
index 2f96df3..4d6d80a 100644
--- a/app/src/main/java/com/morlunk/mumbleclient/channel/PermissionsPopupMenu.java
+++ b/app/src/main/java/com/morlunk/mumbleclient/channel/PermissionsPopupMenu.java
@@ -62,14 +62,20 @@ public class PermissionsPopupMenu implements PopupMenu.OnDismissListener {
}
private int getPermissions() {
- return mChannel.getId() == 0 ? mService.getPermissions() : mChannel.getPermissions();
+ if (mService.isConnected()) {
+ return mChannel.getId() == 0 ? mService.getSession().getPermissions()
+ : mChannel.getPermissions();
+ }
+ return 0;
}
public void show() {
mService.registerObserver(mPermissionsObserver);
if (getPermissions() == 0) {
// onMenuPrepare will be called once more once permissions have loaded.
- mService.requestPermissions(mChannel.getId());
+ if (mService.isConnected()) {
+ mService.getSession().requestPermissions(mChannel.getId());
+ }
} else {
mPrepareListener.onMenuPrepare(mMenu.getMenu(), getPermissions());
}
diff --git a/app/src/main/java/com/morlunk/mumbleclient/channel/ServerInfoFragment.java b/app/src/main/java/com/morlunk/mumbleclient/channel/ServerInfoFragment.java
index ff173b0..7f83bb3 100644
--- a/app/src/main/java/com/morlunk/mumbleclient/channel/ServerInfoFragment.java
+++ b/app/src/main/java/com/morlunk/mumbleclient/channel/ServerInfoFragment.java
@@ -27,6 +27,7 @@ import android.view.ViewGroup;
import android.widget.TextView;
import com.morlunk.jumble.IJumbleService;
+import com.morlunk.jumble.IJumbleSession;
import com.morlunk.jumble.JumbleService;
import com.morlunk.jumble.net.JumbleConnection;
import com.morlunk.jumble.net.JumbleUDPMessageType;
@@ -77,18 +78,19 @@ public class ServerInfoFragment extends JumbleServiceFragment {
* Updates the info from the service.
*/
public void updateData() throws RemoteException {
- if(getService() == null
- || !getService().isSynchronized())
+ if(getService() == null || !getService().isConnected())
return;
- mProtocolView.setText(getString(R.string.server_info_protocol, getService().getServerRelease()));
- mOSVersionView.setText(getString(R.string.server_info_version, getService().getServerOSName(), getService().getServerOSVersion()));
- mTCPLatencyView.setText(getString(R.string.server_info_latency, (float)getService().getTCPLatency()*Math.pow(10, -3)));
- mUDPLatencyView.setText(getString(R.string.server_info_latency, (float)getService().getUDPLatency()*Math.pow(10, -3)));
- mHostView.setText(getString(R.string.server_info_host, getService().getConnectedServer().getHost(), getService().getConnectedServer().getPort()));
+ IJumbleSession session = getService().getSession();
+
+ mProtocolView.setText(getString(R.string.server_info_protocol, session.getServerRelease()));
+ mOSVersionView.setText(getString(R.string.server_info_version, session.getServerOSName(), session.getServerOSVersion()));
+ mTCPLatencyView.setText(getString(R.string.server_info_latency, (float)session.getTCPLatency()*Math.pow(10, -3)));
+ mUDPLatencyView.setText(getString(R.string.server_info_latency, (float)session.getUDPLatency()*Math.pow(10, -3)));
+ mHostView.setText(getString(R.string.server_info_host, getService().getTargetServer().getHost(), getService().getTargetServer().getPort()));
String codecName;
- JumbleUDPMessageType codecType = getService().getCodec();
+ JumbleUDPMessageType codecType = session.getCodec();
switch (codecType) {
case UDPVoiceOpus:
codecName = "Opus";
@@ -106,8 +108,8 @@ public class ServerInfoFragment extends JumbleServiceFragment {
codecName = "???";
}
- mMaxBandwidthView.setText(getString(R.string.server_info_max_bandwidth, (float)getService().getMaxBandwidth()/1000f));
- mCurrentBandwidthView.setText(getString(R.string.server_info_current_bandwidth, (float)getService().getCurrentBandwidth()/1000f));
+ mMaxBandwidthView.setText(getString(R.string.server_info_max_bandwidth, (float)session.getMaxBandwidth()/1000f));
+ mCurrentBandwidthView.setText(getString(R.string.server_info_current_bandwidth, (float)session.getCurrentBandwidth()/1000f));
mCodecView.setText(getString(R.string.server_info_codec, codecName));
}
diff --git a/app/src/main/java/com/morlunk/mumbleclient/channel/UserMenu.java b/app/src/main/java/com/morlunk/mumbleclient/channel/UserMenu.java
index 8a66859..e67a5f0 100644
--- a/app/src/main/java/com/morlunk/mumbleclient/channel/UserMenu.java
+++ b/app/src/main/java/com/morlunk/mumbleclient/channel/UserMenu.java
@@ -21,7 +21,6 @@ import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
-import android.os.RemoteException;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.widget.PopupMenu;
@@ -62,7 +61,7 @@ public class UserMenu implements PermissionsPopupMenu.IOnMenuPrepareListener, Po
@Override
public void onMenuPrepare(Menu menu, int permissions) {
// Use permission data to determine the actions available.
- boolean self = mUser.getSession() == mService.getSession();
+ boolean self = mUser.getSession() == mService.getSessionId();
int perms = mService.getPermissions();
IChannel channel = mUser.getChannel();
int channelPerms = channel.getId() != 0 ? channel.getPermissions() : perms;
@@ -95,7 +94,7 @@ public class UserMenu implements PermissionsPopupMenu.IOnMenuPrepareListener, Po
menu.findItem(R.id.context_ignore_messages).setVisible(!self);
// TODO info
-// informationItem.enabled = (((perms & (Permissions.Write | Permissions.Register))) > 0 || (channelPermissions & (Permissions.Write | Permissions.Enter)) > 0 || (mUser.getSession() == mService.getSession()));
+// informationItem.enabled = (((perms & (Permissions.Write | Permissions.Register))) > 0 || (channelPermissions & (Permissions.Write | Permissions.Enter)) > 0 || (mUser.getSessionId() == mService.getSessionId()));
// Highlight toggles
menu.findItem(R.id.context_mute).setChecked(mUser.isMuted() || mUser.isSuppressed());
diff --git a/app/src/main/java/com/morlunk/mumbleclient/channel/comment/ChannelDescriptionFragment.java b/app/src/main/java/com/morlunk/mumbleclient/channel/comment/ChannelDescriptionFragment.java
index f049d66..4b9708b 100644
--- a/app/src/main/java/com/morlunk/mumbleclient/channel/comment/ChannelDescriptionFragment.java
+++ b/app/src/main/java/com/morlunk/mumbleclient/channel/comment/ChannelDescriptionFragment.java
@@ -31,6 +31,8 @@ public class ChannelDescriptionFragment extends AbstractCommentFragment {
@Override
public void requestComment(final IJumbleService service) {
+ if (!service.isConnected())
+ return;
service.registerObserver(new JumbleObserver() {
@Override
public void onChannelStateUpdated(IChannel channel) {
@@ -41,7 +43,7 @@ public class ChannelDescriptionFragment extends AbstractCommentFragment {
}
}
});
- service.requestChannelDescription(getChannelId());
+ service.getSession().requestChannelDescription(getChannelId());
}
@Override
diff --git a/app/src/main/java/com/morlunk/mumbleclient/channel/comment/UserCommentFragment.java b/app/src/main/java/com/morlunk/mumbleclient/channel/comment/UserCommentFragment.java
index adec7e7..d80dc9c 100644
--- a/app/src/main/java/com/morlunk/mumbleclient/channel/comment/UserCommentFragment.java
+++ b/app/src/main/java/com/morlunk/mumbleclient/channel/comment/UserCommentFragment.java
@@ -31,6 +31,8 @@ public class UserCommentFragment extends AbstractCommentFragment {
@Override
public void requestComment(final IJumbleService service) {
+ if (!service.isConnected())
+ return;
service.registerObserver(new JumbleObserver() {
@Override
public void onUserStateUpdated(IUser user) {
@@ -41,12 +43,14 @@ public class UserCommentFragment extends AbstractCommentFragment {
}
}
});
- service.requestComment(getSession());
+ service.getSession().requestComment(getSession());
}
@Override
public void editComment(IJumbleService service, String comment) {
- service.setUserComment(getSession(), comment);
+ if (!service.isConnected())
+ return;
+ service.getSession().setUserComment(getSession(), comment);
}
public int getSession() {
diff --git a/app/src/main/java/com/morlunk/mumbleclient/service/IPlumbleService.java b/app/src/main/java/com/morlunk/mumbleclient/service/IPlumbleService.java
new file mode 100644
index 0000000..cc5f768
--- /dev/null
+++ b/app/src/main/java/com/morlunk/mumbleclient/service/IPlumbleService.java
@@ -0,0 +1,30 @@
+package com.morlunk.mumbleclient.service;
+
+import com.morlunk.jumble.IJumbleService;
+
+import java.util.List;
+
+/**
+ * Created by andrew on 28/02/17.
+ */
+public interface IPlumbleService extends IJumbleService {
+ void setOverlayShown(boolean showOverlay);
+
+ boolean isOverlayShown();
+
+ void clearChatNotifications();
+
+ void markErrorShown();
+
+ boolean isErrorShown();
+
+ void onTalkKeyDown();
+
+ void onTalkKeyUp();
+
+ List<IChatMessage> getMessageLog();
+
+ void clearMessageLog();
+
+ void setSuppressNotifications(boolean suppressNotifications);
+}
diff --git a/app/src/main/java/com/morlunk/mumbleclient/service/PlumbleOverlay.java b/app/src/main/java/com/morlunk/mumbleclient/service/PlumbleOverlay.java
index 934ea35..7e5bfe4 100644
--- a/app/src/main/java/com/morlunk/mumbleclient/service/PlumbleOverlay.java
+++ b/app/src/main/java/com/morlunk/mumbleclient/service/PlumbleOverlay.java
@@ -19,7 +19,6 @@ package com.morlunk.mumbleclient.service;
import android.content.Context;
import android.graphics.PixelFormat;
-import android.os.RemoteException;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.MotionEvent;
@@ -28,10 +27,8 @@ import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.ListView;
-import com.morlunk.jumble.model.Channel;
import com.morlunk.jumble.model.IChannel;
import com.morlunk.jumble.model.IUser;
-import com.morlunk.jumble.model.User;
import com.morlunk.jumble.util.JumbleObserver;
import com.morlunk.mumbleclient.R;
import com.morlunk.mumbleclient.Settings;
@@ -61,7 +58,7 @@ public class PlumbleOverlay {
@Override
public void onUserJoinedChannel(IUser user, IChannel newChannel, IChannel oldChannel) {
- if(user.getSession() == mService.getSession()) // Session user has changed channels
+ if(user.getSession() == mService.getSessionId()) // Session user has changed channels
mChannelAdapter.setChannel(mService.getSessionChannel());
else if(newChannel.getId() == mService.getSessionChannel().getId() ||
oldChannel.getId() == mService.getSessionChannel().getId())
diff --git a/app/src/main/java/com/morlunk/mumbleclient/service/PlumbleService.java b/app/src/main/java/com/morlunk/mumbleclient/service/PlumbleService.java
index 598127b..30865ba 100644
--- a/app/src/main/java/com/morlunk/mumbleclient/service/PlumbleService.java
+++ b/app/src/main/java/com/morlunk/mumbleclient/service/PlumbleService.java
@@ -19,10 +19,13 @@ package com.morlunk.mumbleclient.service;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
+import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.media.AudioManager;
+import android.os.Binder;
import android.os.Bundle;
+import android.os.IBinder;
import android.os.PowerManager;
import android.preference.PreferenceManager;
import android.speech.tts.TextToSpeech;
@@ -55,7 +58,7 @@ import java.util.List;
public class PlumbleService extends JumbleService implements
SharedPreferences.OnSharedPreferenceChangeListener,
PlumbleConnectionNotification.OnActionListener,
- PlumbleReconnectNotification.OnActionListener {
+ PlumbleReconnectNotification.OnActionListener, IPlumbleService {
/** Undocumented constant that permits a proximity-sensing wake lock. */
public static final int PROXIMITY_SCREEN_OFF_WAKE_LOCK = 32;
public static final int TTS_THRESHOLD = 250; // Maximum number of characters to read
@@ -162,7 +165,7 @@ public class PlumbleService extends JumbleService implements
@Override
public void onUserStateUpdated(IUser user) {
- if(user.getSession() == getSession()) {
+ if(user.getSession() == getSessionId()) {
mSettings.setMutedAndDeafened(user.isSelfMuted(), user.isSelfDeafened()); // Update settings mute/deafen state
if(mNotification != null && !mSuppressNotifications) {
String contentText;
@@ -254,7 +257,7 @@ public class PlumbleService extends JumbleService implements
@Override
public void onUserTalkStateUpdated(IUser user) {
if (isConnectionEstablished() &&
- getSession() == user.getSession() &&
+ getSessionId() == user.getSession() &&
getTransmitMode() == Constants.TRANSMIT_PUSH_TO_TALK &&
user.getTalkState() == TalkState.TALKING &&
mPTTSoundEnabled) {
@@ -294,6 +297,11 @@ public class PlumbleService extends JumbleService implements
}
@Override
+ public IBinder onBind(Intent intent) {
+ return new PlumbleBinder(this);
+ }
+
+ @Override
public void onDestroy() {
if (mNotification != null) {
mNotification.hide();
@@ -505,6 +513,7 @@ public class PlumbleService extends JumbleService implements
super.cancelReconnect();
}
+ @Override
public void setOverlayShown(boolean showOverlay) {
if(!mChannelOverlay.isShown()) {
mChannelOverlay.show();
@@ -513,14 +522,17 @@ public class PlumbleService extends JumbleService implements
}
}
+ @Override
public boolean isOverlayShown() {
return mChannelOverlay.isShown();
}
+ @Override
public void clearChatNotifications() {
mMessageNotification.dismiss();
}
+ @Override
public void markErrorShown() {
mErrorShown = true;
// Dismiss the reconnection prompt if a reconnection isn't in progress.
@@ -530,6 +542,7 @@ public class PlumbleService extends JumbleService implements
}
}
+ @Override
public boolean isErrorShown() {
return mErrorShown;
}
@@ -538,6 +551,7 @@ public class PlumbleService extends JumbleService implements
* Called when a user presses a talk key down (i.e. when they want to talk).
* Accounts for talk logic if toggle PTT is on.
*/
+ @Override
public void onTalkKeyDown() {
if(isConnectionEstablished()
&& Settings.ARRAY_INPUT_METHOD_PTT.equals(mSettings.getInputMethod())) {
@@ -551,6 +565,7 @@ public class PlumbleService extends JumbleService implements
* Called when a user releases a talk key (i.e. when they do not want to talk).
* Accounts for talk logic if toggle PTT is on.
*/
+ @Override
public void onTalkKeyUp() {
if(isConnectionEstablished()
&& Settings.ARRAY_INPUT_METHOD_PTT.equals(mSettings.getInputMethod())) {
@@ -562,10 +577,12 @@ public class PlumbleService extends JumbleService implements
}
}
+ @Override
public List<IChatMessage> getMessageLog() {
return Collections.unmodifiableList(mMessageLog);
}
+ @Override
public void clearMessageLog() {
mMessageLog.clear();
}
@@ -581,7 +598,20 @@ public class PlumbleService extends JumbleService implements
*
* @param suppressNotifications true if Plumble is to disable notifications.
*/
+ @Override
public void setSuppressNotifications(boolean suppressNotifications) {
mSuppressNotifications = suppressNotifications;
}
+
+ public static class PlumbleBinder extends Binder {
+ private final PlumbleService mService;
+
+ private PlumbleBinder(PlumbleService service) {
+ mService = service;
+ }
+
+ public IPlumbleService getService() {
+ return mService;
+ }
+ }
}
diff --git a/app/src/main/java/com/morlunk/mumbleclient/service/ipc/TalkBroadcastReceiver.java b/app/src/main/java/com/morlunk/mumbleclient/service/ipc/TalkBroadcastReceiver.java
index 9166fbf..4a8853a 100644
--- a/app/src/main/java/com/morlunk/mumbleclient/service/ipc/TalkBroadcastReceiver.java
+++ b/app/src/main/java/com/morlunk/mumbleclient/service/ipc/TalkBroadcastReceiver.java
@@ -22,6 +22,7 @@ import android.content.Context;
import android.content.Intent;
import com.morlunk.jumble.IJumbleService;
+import com.morlunk.jumble.IJumbleSession;
/**
* Created by andrew on 08/08/14.
@@ -42,14 +43,17 @@ public class TalkBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (BROADCAST_TALK.equals(intent.getAction())) {
+ if (!mService.isConnected())
+ return;
+ IJumbleSession session = mService.getSession();
String status = intent.getStringExtra(EXTRA_TALK_STATUS);
if (status == null) status = TALK_STATUS_TOGGLE;
if (TALK_STATUS_ON.equals(status)) {
- mService.setTalkingState(true);
+ session.setTalkingState(true);
} else if (TALK_STATUS_OFF.equals(status)) {
- mService.setTalkingState(false);
+ session.setTalkingState(false);
} else if (TALK_STATUS_TOGGLE.equals(status)) {
- mService.setTalkingState(!mService.isTalking());
+ session.setTalkingState(!session.isTalking());
}
} else {
throw new UnsupportedOperationException();
diff --git a/app/src/main/java/com/morlunk/mumbleclient/util/JumbleServiceFragment.java b/app/src/main/java/com/morlunk/mumbleclient/util/JumbleServiceFragment.java
index cde3c7c..c7f57ea 100644
--- a/app/src/main/java/com/morlunk/mumbleclient/util/JumbleServiceFragment.java
+++ b/app/src/main/java/com/morlunk/mumbleclient/util/JumbleServiceFragment.java
@@ -26,6 +26,7 @@ import android.view.View;
import com.morlunk.jumble.IJumbleService;
import com.morlunk.jumble.util.IJumbleObserver;
+import com.morlunk.mumbleclient.service.IPlumbleService;
import com.morlunk.mumbleclient.service.PlumbleService;
/**
@@ -99,7 +100,7 @@ public abstract class JumbleServiceFragment extends Fragment {
onServiceDetached(mServiceProvider.getService());
}
- public PlumbleService getService() {
+ public IPlumbleService getService() {
return mServiceProvider.getService();
}
}
diff --git a/app/src/main/java/com/morlunk/mumbleclient/util/JumbleServiceProvider.java b/app/src/main/java/com/morlunk/mumbleclient/util/JumbleServiceProvider.java
index 797c68a..36ac810 100644
--- a/app/src/main/java/com/morlunk/mumbleclient/util/JumbleServiceProvider.java
+++ b/app/src/main/java/com/morlunk/mumbleclient/util/JumbleServiceProvider.java
@@ -18,13 +18,14 @@
package com.morlunk.mumbleclient.util;
import com.morlunk.jumble.IJumbleService;
+import com.morlunk.mumbleclient.service.IPlumbleService;
import com.morlunk.mumbleclient.service.PlumbleService;
/**
* Created by andrew on 03/08/13.
*/
public interface JumbleServiceProvider {
- PlumbleService getService();
+ IPlumbleService getService();
void addServiceFragment(JumbleServiceFragment fragment);
void removeServiceFragment(JumbleServiceFragment fragment);
}
diff --git a/libraries/Jumble b/libraries/Jumble
-Subproject dfdd83dee1707ddc90776e0483ad1b5f9c9db29
+Subproject 4a44ab69bdf4bd2c755f694dbac95fcc0637307