Skip to content
Snippets Groups Projects
Commit 92ba16c3 authored by Janne Mareike Koschinski's avatar Janne Mareike Koschinski
Browse files

Improved code, refactored it a bit, implemented full null safety

parent 146177e8
Branches
Tags
No related merge requests found
Showing
with 207 additions and 119 deletions
...@@ -23,7 +23,8 @@ android { ...@@ -23,7 +23,8 @@ android {
applicationVariants.all { variant -> applicationVariants.all { variant ->
variant.outputs.each { output -> variant.outputs.each { output ->
output.outputFile = new File(output.outputFile.parent, output.outputFile.name.replace(".apk", "-" + defaultConfig.versionName + "-build" + versionCode + ".apk")) def fileName = output.outputFile.name.replace(".apk", String.format("-%s-build%d.apk", defaultConfig.versionName, versionCode))
output.outputFile = new File(output.outputFile.parent, fileName)
} }
} }
} }
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
<application <application
android:allowBackup="true" android:allowBackup="true"
android:fullBackupContent="true"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:label="@string/app_name" android:label="@string/app_name"
android:supportsRtl="true" android:supportsRtl="true"
...@@ -23,14 +24,6 @@ ...@@ -23,14 +24,6 @@
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity> </activity>
<activity
android:name=".ui.coresetup.CoreSetupActivity"
android:label="@string/title_activity_core_setup"
android:parentActivityName=".ui.chat.ChatActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".ui.chat.MainActivity" />
</activity>
</application> </application>
</manifest> </manifest>
package de.kuschku.libquassel; package de.kuschku.libquassel;
import android.support.annotation.NonNull;
import java.util.UUID; import java.util.UUID;
import de.greenrobot.event.EventBus; import de.greenrobot.event.EventBus;
public class BusProvider { public class BusProvider {
public final String id; @NonNull private final String id;
public final EventBus handle; @NonNull public final EventBus handle;
public final EventBus dispatch; @NonNull public final EventBus dispatch;
@NonNull
public final EventBus event; public final EventBus event;
public BusProvider() { public BusProvider() {
...@@ -28,4 +31,11 @@ public class BusProvider { ...@@ -28,4 +31,11 @@ public class BusProvider {
public void sendEvent(Object o) { public void sendEvent(Object o) {
this.event.post(o); this.event.post(o);
} }
@Override
public String toString() {
return "BusProvider{" +
"id='" + id + '\'' +
'}';
}
} }
package de.kuschku.libquassel; package de.kuschku.libquassel;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
...@@ -28,36 +31,42 @@ import de.kuschku.util.backports.Stream; ...@@ -28,36 +31,42 @@ import de.kuschku.util.backports.Stream;
import de.kuschku.util.observables.callbacks.UICallback; import de.kuschku.util.observables.callbacks.UICallback;
import de.kuschku.util.observables.lists.IObservableList; import de.kuschku.util.observables.lists.IObservableList;
import de.kuschku.util.observables.lists.ObservableComparableSortedList; import de.kuschku.util.observables.lists.ObservableComparableSortedList;
import de.kuschku.util.observables.lists.ObservableSortedList;
import static de.kuschku.util.AndroidAssert.*;
public class Client { public class Client {
@NonNull
private final Map<Integer, Network> networks = new HashMap<>(); private final Map<Integer, Network> networks = new HashMap<>();
@NonNull
private final IObservableList<UICallback, NetworkWrapper> networkList = new ObservableComparableSortedList<>(NetworkWrapper.class); private final IObservableList<UICallback, NetworkWrapper> networkList = new ObservableComparableSortedList<>(NetworkWrapper.class);
@NonNull
private final Map<Integer, Buffer> buffers = new HashMap<>(); private final Map<Integer, Buffer> buffers = new HashMap<>();
@NonNull
private final List<String> initDataQueue = new ArrayList<>(); private final List<String> initDataQueue = new ArrayList<>();
@NonNull
private final BacklogManager backlogManager; private final BacklogManager backlogManager;
@NonNull
private final BusProvider busProvider; private final BusProvider busProvider;
public int lag; public int lag;
public int openBuffer;
public int openBufferView;
private ConnectionChangeEvent.Status connectionStatus; private ConnectionChangeEvent.Status connectionStatus;
private ClientInitAck core; private ClientInitAck core;
@Nullable
private SessionState state; private SessionState state;
private BufferViewManager bufferViewManager; private BufferViewManager bufferViewManager;
private BufferSyncer bufferSyncer; private BufferSyncer bufferSyncer;
private ClientData clientData; private ClientData clientData;
public Client(final BusProvider busProvider) { public Client(@NonNull final BusProvider busProvider) {
this(new SimpleBacklogManager(busProvider), busProvider); this(new SimpleBacklogManager(busProvider), busProvider);
} }
public Client(final BacklogManager backlogManager, final BusProvider busProvider) { public Client(@NonNull final BacklogManager backlogManager, @NonNull final BusProvider busProvider) {
this.backlogManager = backlogManager; this.backlogManager = backlogManager;
this.busProvider = busProvider; this.busProvider = busProvider;
} }
public void sendInput(final BufferInfo info, final String input) { public void sendInput(@NonNull final BufferInfo info, @NonNull final String input) {
busProvider.dispatch(new RpcCallFunction( busProvider.dispatch(new RpcCallFunction(
"2sendInput(BufferInfo,QString)", "2sendInput(BufferInfo,QString)",
new QVariant<>(info), new QVariant<>(info),
...@@ -65,74 +74,90 @@ public class Client { ...@@ -65,74 +74,90 @@ public class Client {
)); ));
} }
public void displayMsg(final Message message) { public void displayMsg(@NonNull final Message message) {
backlogManager.displayMessage(message.bufferInfo.id, message); backlogManager.displayMessage(message.bufferInfo.id, message);
} }
public void displayStatusMsg(String scope, String message) { public void displayStatusMsg(@NonNull String scope, @NonNull String message) {
busProvider.sendEvent(new StatusMessageEvent(scope, message)); busProvider.sendEvent(new StatusMessageEvent(scope, message));
} }
public void putNetwork(final Network network) { public void putNetwork(@NonNull final Network network) {
assertNotNull(state);
networks.put(network.getNetworkId(), network); networks.put(network.getNetworkId(), network);
for (BufferInfo info : getState().BufferInfos) { for (BufferInfo info : state.BufferInfos) {
if (info.networkId == network.getNetworkId()) { if (info.networkId == network.getNetworkId()) {
putBuffer(Buffers.fromType(info, network)); Buffer buffer = Buffers.fromType(info, network);
assertNotNull(buffer);
putBuffer(buffer);
} }
} }
} }
@Nullable
public Network getNetwork(final int networkId) { public Network getNetwork(final int networkId) {
return this.networks.get(networkId); return this.networks.get(networkId);
} }
public void putBuffer(final Buffer buffer) { public void putBuffer(@NonNull final Buffer buffer) {
this.buffers.put(buffer.getInfo().id, buffer); this.buffers.put(buffer.getInfo().id, buffer);
} }
@Nullable
public Buffer getBuffer(final int bufferId) { public Buffer getBuffer(final int bufferId) {
return this.buffers.get(bufferId); return this.buffers.get(bufferId);
} }
void sendInitRequest(final String className, final String objectName) { void sendInitRequest(@NonNull final String className, @Nullable final String objectName) {
sendInitRequest(className, objectName, false); sendInitRequest(className, objectName, false);
} }
void sendInitRequest(final String className, final String objectName, boolean addToList) { void sendInitRequest(@NonNull final String className, @Nullable final String objectName, boolean addToList) {
busProvider.dispatch(new InitRequestFunction(className, objectName)); busProvider.dispatch(new InitRequestFunction(className, objectName));
if (addToList) if (addToList)
getInitDataQueue().add(className + ":" + objectName); getInitDataQueue().add(className + ":" + objectName);
} }
public void __objectRenamed__(String className, String newName, String oldName) { public void __objectRenamed__(@NonNull String className, @NonNull String newName, @NonNull String oldName) {
safeGetObjectByIdentifier(className, oldName).renameObject(newName); safeGetObjectByIdentifier(className, oldName).renameObject(newName);
} }
private SyncableObject safeGetObjectByIdentifier(String className, String oldName) { @NonNull
private SyncableObject safeGetObjectByIdentifier(@NonNull String className, @NonNull String oldName) {
SyncableObject val = getObjectByIdentifier(className, oldName); SyncableObject val = getObjectByIdentifier(className, oldName);
if (val == null) throw new IllegalArgumentException(String.format("Object %s::%s does not exist", className, oldName)); if (val == null) throw new IllegalArgumentException(String.format("Object %s::%s does not exist", className, oldName));
else return val; else return val;
} }
public SyncableObject getObjectByIdentifier(final String className, final String objectName) { @Nullable
public SyncableObject getObjectByIdentifier(@NonNull final String className, @NonNull final String objectName) {
switch (className) { switch (className) {
case "BacklogManager": case "BacklogManager":
return getBacklogManager(); return getBacklogManager();
case "IrcChannel": { case "IrcChannel": {
final int networkId = Integer.parseInt(objectName.split("/")[0]); final int networkId = Integer.parseInt(objectName.split("/")[0]);
final String channelname = objectName.split("/")[1]; final String channelname = objectName.split("/")[1];
return getNetwork(networkId).getChannels().get(channelname);
// Assert that networkId is valid
Network network = getNetwork(networkId);
assertNotNull(network);
return network.getChannels().get(channelname);
} }
case "BufferSyncer": case "BufferSyncer":
return bufferSyncer; return bufferSyncer;
case "BufferViewConfig": case "BufferViewConfig":
assertNotNull(getBufferViewManager());
return getBufferViewManager().BufferViews.get(Integer.valueOf(objectName)); return getBufferViewManager().BufferViews.get(Integer.valueOf(objectName));
case "IrcUser": { case "IrcUser": {
final int networkId = Integer.parseInt(objectName.split("/")[0]); final int networkId = Integer.parseInt(objectName.split("/")[0]);
final String username = objectName.split("/")[1]; final String username = objectName.split("/")[1];
Network network = getNetwork(networkId); Network network = getNetwork(networkId);
assertNotNull(network);
return network.getUser(username); return network.getUser(username);
} }
case "Network": { case "Network": {
...@@ -143,27 +168,31 @@ public class Client { ...@@ -143,27 +168,31 @@ public class Client {
} }
} }
@Nullable
public SessionState getState() { public SessionState getState() {
return state; return state;
} }
public void setState(SessionState state) { public void setState(@Nullable SessionState state) {
this.state = state; this.state = state;
} }
@NonNull
public List<String> getInitDataQueue() { public List<String> getInitDataQueue() {
return initDataQueue; return initDataQueue;
} }
@NonNull
public BacklogManager getBacklogManager() { public BacklogManager getBacklogManager() {
return backlogManager; return backlogManager;
} }
@Nullable
public BufferViewManager getBufferViewManager() { public BufferViewManager getBufferViewManager() {
return bufferViewManager; return bufferViewManager;
} }
public void setBufferViewManager(final BufferViewManager bufferViewManager) { public void setBufferViewManager(@NonNull final BufferViewManager bufferViewManager) {
this.bufferViewManager = bufferViewManager; this.bufferViewManager = bufferViewManager;
for (int id : bufferViewManager.BufferViews.keySet()) { for (int id : bufferViewManager.BufferViews.keySet()) {
sendInitRequest("BufferViewConfig", String.valueOf(id), true); sendInitRequest("BufferViewConfig", String.valueOf(id), true);
...@@ -190,23 +219,27 @@ public class Client { ...@@ -190,23 +219,27 @@ public class Client {
this.clientData = clientData; this.clientData = clientData;
} }
@NonNull
public Collection<Buffer> getBuffers(int networkId) { public Collection<Buffer> getBuffers(int networkId) {
return new Stream<>(this.buffers.values()).filter(buffer -> buffer.getInfo().networkId == networkId).list(); return new Stream<>(this.buffers.values()).filter(buffer -> buffer.getInfo().networkId == networkId).list();
} }
@NonNull
public Collection<Network> getNetworks() { public Collection<Network> getNetworks() {
return networks.values(); return networks.values();
} }
@NonNull
public ConnectionChangeEvent.Status getConnectionStatus() { public ConnectionChangeEvent.Status getConnectionStatus() {
return connectionStatus; return connectionStatus;
} }
public void setConnectionStatus(final ConnectionChangeEvent.Status connectionStatus) { public void setConnectionStatus(@NonNull final ConnectionChangeEvent.Status connectionStatus) {
this.connectionStatus = connectionStatus; this.connectionStatus = connectionStatus;
busProvider.sendEvent(new ConnectionChangeEvent(connectionStatus)); busProvider.sendEvent(new ConnectionChangeEvent(connectionStatus));
} }
@NonNull
public IObservableList<UICallback, NetworkWrapper> getNetworkList() { public IObservableList<UICallback, NetworkWrapper> getNetworkList() {
return networkList; return networkList;
} }
......
package de.kuschku.libquassel; package de.kuschku.libquassel;
import android.support.annotation.NonNull;
import java.util.Arrays; import java.util.Arrays;
public class ClientData { public class ClientData {
/** /**
* The flags the client supports. * The flags the client supports.
*/ */
@NonNull
public final FeatureFlags flags; public final FeatureFlags flags;
/** /**
* The list of protocols supported, 0x01 is Legacy and 0x02 is Datastream. * The list of protocols supported, 0x01 is Legacy and 0x02 is Datastream.
*/ */
public final int[] supportedProtocols; @NonNull
public final byte[] supportedProtocols;
/** /**
* A string identifying the client. * A string identifying the client.
*/ */
@NonNull
public final String identifier; public final String identifier;
/** /**
...@@ -23,17 +28,19 @@ public class ClientData { ...@@ -23,17 +28,19 @@ public class ClientData {
*/ */
public final int protocolVersion; public final int protocolVersion;
public ClientData(FeatureFlags flags, int[] supportedProtocols, String identifier, int protocolVersion) { public ClientData(@NonNull FeatureFlags flags, @NonNull byte[] supportedProtocols, @NonNull String identifier, int protocolVersion) {
this.flags = flags; this.flags = flags;
this.supportedProtocols = supportedProtocols.clone(); this.supportedProtocols = supportedProtocols;
this.identifier = identifier; this.identifier = identifier;
this.protocolVersion = protocolVersion; this.protocolVersion = protocolVersion;
} }
public int[] getSupportedProtocols() { @NonNull
public byte[] getSupportedProtocols() {
return supportedProtocols; return supportedProtocols;
} }
@NonNull
@Override @Override
public String toString() { public String toString() {
return "ClientData{" + return "ClientData{" +
...@@ -62,6 +69,7 @@ public class ClientData { ...@@ -62,6 +69,7 @@ public class ClientData {
(this.supportsCompression ? 0x02 : 0x00)); (this.supportsCompression ? 0x02 : 0x00));
} }
@NonNull
@Override @Override
public String toString() { public String toString() {
return "FeatureFlags{" + return "FeatureFlags{" +
......
package de.kuschku.libquassel; package de.kuschku.libquassel;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log; import android.util.Log;
import java.io.IOException; import java.io.IOException;
...@@ -29,6 +31,7 @@ import de.kuschku.util.ServerAddress; ...@@ -29,6 +31,7 @@ import de.kuschku.util.ServerAddress;
import de.kuschku.util.niohelpers.WrappedChannel; import de.kuschku.util.niohelpers.WrappedChannel;
import static de.kuschku.libquassel.primitives.QMetaType.Type.UInt; import static de.kuschku.libquassel.primitives.QMetaType.Type.UInt;
import static de.kuschku.util.AndroidAssert.*;
/** /**
* Starts a connection to a core and handles the data in the backend. * Starts a connection to a core and handles the data in the backend.
...@@ -38,23 +41,34 @@ import static de.kuschku.libquassel.primitives.QMetaType.Type.UInt; ...@@ -38,23 +41,34 @@ import static de.kuschku.libquassel.primitives.QMetaType.Type.UInt;
*/ */
public class CoreConnection { public class CoreConnection {
@NonNull
private final ServerAddress address; private final ServerAddress address;
@Nullable
private ExecutorService outputExecutor; private ExecutorService outputExecutor;
@Nullable
private ExecutorService inputExecutor; private ExecutorService inputExecutor;
@Nullable
private RemotePeer remotePeer; private RemotePeer remotePeer;
private ClientData clientData; @NonNull
private BusProvider busProvider; private final ClientData clientData;
@NonNull
private final BusProvider busProvider;
@Nullable
private WrappedChannel channel; private WrappedChannel channel;
@Nullable
private Socket socket; private Socket socket;
private ConnectionChangeEvent.Status status; @NonNull
private ConnectionChangeEvent.Status status = ConnectionChangeEvent.Status.DISCONNECTED;
@Nullable
private Client client; private Client client;
public CoreConnection(final ServerAddress address, final ClientData clientData, final BusProvider busProvider) { public CoreConnection(@NonNull final ServerAddress address, @NonNull final ClientData clientData, @NonNull final BusProvider busProvider) {
this.address = address; this.address = address;
this.clientData = clientData; this.clientData = clientData;
this.busProvider = busProvider; this.busProvider = busProvider;
} }
@NonNull
public ConnectionChangeEvent.Status getStatus() { public ConnectionChangeEvent.Status getStatus() {
return status; return status;
} }
...@@ -66,6 +80,8 @@ public class CoreConnection { ...@@ -66,6 +80,8 @@ public class CoreConnection {
* @param supportsKeepAlive If the connection may use keepAlive * @param supportsKeepAlive If the connection may use keepAlive
*/ */
public void open(boolean supportsKeepAlive) throws IOException { public void open(boolean supportsKeepAlive) throws IOException {
assertNotNull(client);
// Intialize socket // Intialize socket
socket = new Socket(); socket = new Socket();
if (supportsKeepAlive) socket.setKeepAlive(true); if (supportsKeepAlive) socket.setKeepAlive(true);
...@@ -91,6 +107,8 @@ public class CoreConnection { ...@@ -91,6 +107,8 @@ public class CoreConnection {
* @throws IOException * @throws IOException
*/ */
public void close() throws IOException { public void close() throws IOException {
assertNotNull(client);
client.setConnectionStatus(ConnectionChangeEvent.Status.DISCONNECTED); client.setConnectionStatus(ConnectionChangeEvent.Status.DISCONNECTED);
// We can do this because we clean up the file handles ourselves // We can do this because we clean up the file handles ourselves
...@@ -102,22 +120,29 @@ public class CoreConnection { ...@@ -102,22 +120,29 @@ public class CoreConnection {
if (socket != null) socket.close(); if (socket != null) socket.close();
} }
@Nullable
public ExecutorService getOutputExecutor() { public ExecutorService getOutputExecutor() {
return outputExecutor; return outputExecutor;
} }
@NonNull
public ClientData getClientData() { public ClientData getClientData() {
return clientData; return clientData;
} }
@NonNull
public WrappedChannel getChannel() { public WrappedChannel getChannel() {
assertNotNull(channel);
return channel; return channel;
} }
@Nullable
public RemotePeer getRemotePeer() { public RemotePeer getRemotePeer() {
return remotePeer; return remotePeer;
} }
@Nullable
public Socket getSocket() { public Socket getSocket() {
return socket; return socket;
} }
...@@ -128,6 +153,9 @@ public class CoreConnection { ...@@ -128,6 +153,9 @@ public class CoreConnection {
* @throws IOException * @throws IOException
*/ */
private void handshake() throws IOException { private void handshake() throws IOException {
assertNotNull(channel);
assertNotNull(inputExecutor);
// Start protocol handshake with magic version and feature flags // Start protocol handshake with magic version and feature flags
QMetaTypeRegistry.serialize(UInt, channel, 0x42b33f00 | clientData.flags.flags); QMetaTypeRegistry.serialize(UInt, channel, 0x42b33f00 | clientData.flags.flags);
...@@ -149,15 +177,15 @@ public class CoreConnection { ...@@ -149,15 +177,15 @@ public class CoreConnection {
} }
} }
public void onEventAsync(ConnectionChangeEvent event) { public void onEventAsync(@NonNull ConnectionChangeEvent event) {
this.status = event.status; this.status = event.status;
} }
public void setCompression(boolean supportsCompression) throws IOException { public void setCompression(boolean supportsCompression) {
if (supportsCompression) channel = WrappedChannel.withCompression(channel); if (supportsCompression) channel = WrappedChannel.withCompression(getChannel());
} }
public void setClient(Client client) { public void setClient(@NonNull Client client) {
this.client = client; this.client = client;
} }
...@@ -165,15 +193,16 @@ public class CoreConnection { ...@@ -165,15 +193,16 @@ public class CoreConnection {
* A runnable that reads from the channel and calls the functions responsible for processing the read data. * A runnable that reads from the channel and calls the functions responsible for processing the read data.
*/ */
private class ReadRunnable implements Runnable { private class ReadRunnable implements Runnable {
public boolean running = true;
@Override @Override
public void run() { public void run() {
assertNotNull(client);
try { try {
boolean hasReadPreHandshake = false; boolean hasReadPreHandshake = false;
while (running) { while (true) {
if (!hasReadPreHandshake) { if (!hasReadPreHandshake) {
final ByteBuffer buffer = ByteBuffer.allocate(4); final ByteBuffer buffer = ByteBuffer.allocate(4);
assertNotNull(buffer);
getChannel().read(buffer); getChannel().read(buffer);
final Protocol protocol = ProtocolSerializer.get().deserialize(buffer); final Protocol protocol = ProtocolSerializer.get().deserialize(buffer);
...@@ -199,8 +228,10 @@ public class CoreConnection { ...@@ -199,8 +228,10 @@ public class CoreConnection {
hasReadPreHandshake = true; hasReadPreHandshake = true;
// Send client data to core // Send client data to core
String clientDate = new SimpleDateFormat("MMM dd yyyy HH:mm:ss", Locale.US).format(new Date());
assertNotNull(clientDate);
busProvider.dispatch(new HandshakeFunction(new ClientInit( busProvider.dispatch(new HandshakeFunction(new ClientInit(
new SimpleDateFormat("MMM dd yyyy HH:mm:ss", Locale.US).format(new Date()), clientDate,
protocol.protocolFlags.supportsSSL, protocol.protocolFlags.supportsSSL,
getClientData().identifier, getClientData().identifier,
false, false,
......
package de.kuschku.libquassel; package de.kuschku.libquassel;
import android.support.annotation.NonNull;
import de.kuschku.libquassel.functions.types.InitDataFunction; import de.kuschku.libquassel.functions.types.InitDataFunction;
import de.kuschku.libquassel.functions.types.InitRequestFunction; import de.kuschku.libquassel.functions.types.InitRequestFunction;
import de.kuschku.libquassel.functions.types.RpcCallFunction; import de.kuschku.libquassel.functions.types.RpcCallFunction;
...@@ -29,5 +31,6 @@ public interface IProtocolHandler { ...@@ -29,5 +31,6 @@ public interface IProtocolHandler {
void onEventMainThread(SessionInit message); void onEventMainThread(SessionInit message);
@NonNull
Client getClient(); Client getClient();
} }
package de.kuschku.libquassel; package de.kuschku.libquassel;
import android.support.annotation.NonNull;
import android.util.Log; import android.util.Log;
import de.kuschku.libquassel.events.ConnectionChangeEvent; import de.kuschku.libquassel.events.ConnectionChangeEvent;
...@@ -19,20 +20,24 @@ import de.kuschku.libquassel.objects.types.ClientLoginReject; ...@@ -19,20 +20,24 @@ import de.kuschku.libquassel.objects.types.ClientLoginReject;
import de.kuschku.libquassel.objects.types.SessionInit; import de.kuschku.libquassel.objects.types.SessionInit;
import de.kuschku.libquassel.primitives.types.BufferInfo; import de.kuschku.libquassel.primitives.types.BufferInfo;
import de.kuschku.libquassel.syncables.SyncableRegistry; import de.kuschku.libquassel.syncables.SyncableRegistry;
import de.kuschku.libquassel.syncables.types.SyncableObject;
import de.kuschku.util.AndroidAssert;
import de.kuschku.util.ReflectionUtils; import de.kuschku.util.ReflectionUtils;
public class ProtocolHandler implements IProtocolHandler { public class ProtocolHandler implements IProtocolHandler {
@NonNull
public final Client client; public final Client client;
private BusProvider busProvider; @NonNull
private final BusProvider busProvider;
public ProtocolHandler(BusProvider busProvider) { public ProtocolHandler(@NonNull BusProvider busProvider) {
this.busProvider = busProvider; this.busProvider = busProvider;
this.busProvider.handle.register(this); this.busProvider.handle.register(this);
this.busProvider.event.register(this); this.busProvider.event.register(this);
this.client = new Client(busProvider); this.client = new Client(busProvider);
} }
public void onEventMainThread(InitDataFunction packedFunc) { public void onEventMainThread(@NonNull InitDataFunction packedFunc) {
try { try {
if (client.getConnectionStatus() == ConnectionChangeEvent.Status.CONNECTED) { if (client.getConnectionStatus() == ConnectionChangeEvent.Status.CONNECTED) {
if (!packedFunc.className.equals("IrcUser")) if (!packedFunc.className.equals("IrcUser"))
...@@ -45,7 +50,10 @@ public class ProtocolHandler implements IProtocolHandler { ...@@ -45,7 +50,10 @@ public class ProtocolHandler implements IProtocolHandler {
} }
} }
} }
SyncableRegistry.from(packedFunc).init(packedFunc, busProvider, client); SyncableObject object = SyncableRegistry.from(packedFunc);
AndroidAssert.assertNotNull(object);
object.init(packedFunc, busProvider, client);
} catch (Exception e) { } catch (Exception e) {
busProvider.sendEvent(new GeneralErrorEvent(e)); busProvider.sendEvent(new GeneralErrorEvent(e));
} }
...@@ -54,7 +62,7 @@ public class ProtocolHandler implements IProtocolHandler { ...@@ -54,7 +62,7 @@ public class ProtocolHandler implements IProtocolHandler {
public void onEventMainThread(InitRequestFunction packedFunc) { public void onEventMainThread(InitRequestFunction packedFunc) {
} }
public void onEventMainThread(RpcCallFunction packedFunc) { public void onEventMainThread(@NonNull RpcCallFunction packedFunc) {
try { try {
if (packedFunc.functionName.substring(0, 1).equals("2")) { if (packedFunc.functionName.substring(0, 1).equals("2")) {
ReflectionUtils.invokeMethod(client, packedFunc.functionName.substring(1), packedFunc.params); ReflectionUtils.invokeMethod(client, packedFunc.functionName.substring(1), packedFunc.params);
...@@ -68,7 +76,7 @@ public class ProtocolHandler implements IProtocolHandler { ...@@ -68,7 +76,7 @@ public class ProtocolHandler implements IProtocolHandler {
} }
} }
public void onEventMainThread(SyncFunction packedFunc) { public void onEventMainThread(@NonNull SyncFunction packedFunc) {
try { try {
final Object syncable = client.getObjectByIdentifier(packedFunc.className, packedFunc.objectName); final Object syncable = client.getObjectByIdentifier(packedFunc.className, packedFunc.objectName);
if (syncable != null) { if (syncable != null) {
...@@ -81,7 +89,7 @@ public class ProtocolHandler implements IProtocolHandler { ...@@ -81,7 +89,7 @@ public class ProtocolHandler implements IProtocolHandler {
} }
} }
public void onEventMainThread(ClientInitReject message) { public void onEventMainThread(@NonNull ClientInitReject message) {
busProvider.sendEvent(new HandshakeFailedEvent(message.Error)); busProvider.sendEvent(new HandshakeFailedEvent(message.Error));
} }
...@@ -102,11 +110,11 @@ public class ProtocolHandler implements IProtocolHandler { ...@@ -102,11 +110,11 @@ public class ProtocolHandler implements IProtocolHandler {
client.setConnectionStatus(ConnectionChangeEvent.Status.CONNECTING); client.setConnectionStatus(ConnectionChangeEvent.Status.CONNECTING);
} }
public void onEventMainThread(ClientLoginReject message) { public void onEventMainThread(@NonNull ClientLoginReject message) {
busProvider.sendEvent(new LoginFailedEvent(message.Error)); busProvider.sendEvent(new LoginFailedEvent(message.Error));
} }
public void onEventMainThread(SessionInit message) { public void onEventMainThread(@NonNull SessionInit message) {
client.setState(message.SessionState); client.setState(message.SessionState);
client.setConnectionStatus(ConnectionChangeEvent.Status.INITIALIZING_DATA); client.setConnectionStatus(ConnectionChangeEvent.Status.INITIALIZING_DATA);
...@@ -126,6 +134,7 @@ public class ProtocolHandler implements IProtocolHandler { ...@@ -126,6 +134,7 @@ public class ProtocolHandler implements IProtocolHandler {
} }
} }
@NonNull
@Override @Override
public Client getClient() { public Client getClient() {
return client; return client;
......
package de.kuschku.libquassel.backlogmanagers; package de.kuschku.libquassel.backlogmanagers;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
...@@ -13,13 +14,13 @@ import de.kuschku.util.observables.lists.ObservableSortedList; ...@@ -13,13 +14,13 @@ import de.kuschku.util.observables.lists.ObservableSortedList;
public abstract class BacklogManager extends SyncableObject { public abstract class BacklogManager extends SyncableObject {
public abstract void requestBacklog(int bufferId, int from, int to, int count, int extra); public abstract void requestBacklog(int bufferId, int from, int to, int count, int extra);
public abstract void receiveBacklog(int bufferId, int from, int to, int count, int extra, List<Message> messages); public abstract void receiveBacklog(int bufferId, int from, int to, int count, int extra, @NonNull List<Message> messages);
public abstract void displayMessage(int bufferId, Message message); public abstract void displayMessage(int bufferId, @NonNull Message message);
public abstract ObservableSortedList<Message> get(int bufferId); public abstract ObservableSortedList<Message> get(int bufferId);
public abstract void bind(int bufferId, @Nullable RecyclerView.Adapter adapter, AutoScroller scroller); public abstract void bind(int bufferId, @NonNull RecyclerView.Adapter adapter, @Nullable AutoScroller scroller);
public abstract void requestMoreBacklog(int bufferId, int count); public abstract void requestMoreBacklog(int bufferId, int count);
} }
package de.kuschku.libquassel.backlogmanagers; package de.kuschku.libquassel.backlogmanagers;
import android.support.annotation.IntRange;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.util.SparseArray; import android.util.SparseArray;
...@@ -16,15 +18,19 @@ import de.kuschku.libquassel.functions.types.SyncFunction; ...@@ -16,15 +18,19 @@ import de.kuschku.libquassel.functions.types.SyncFunction;
import de.kuschku.libquassel.message.Message; import de.kuschku.libquassel.message.Message;
import de.kuschku.libquassel.primitives.types.QVariant; import de.kuschku.libquassel.primitives.types.QVariant;
import de.kuschku.util.observables.AutoScroller; import de.kuschku.util.observables.AutoScroller;
import de.kuschku.util.observables.callbacks.wrappers.AdapterUICallbackWrapper;
import de.kuschku.util.observables.lists.ObservableComparableSortedList; import de.kuschku.util.observables.lists.ObservableComparableSortedList;
import de.kuschku.util.observables.lists.ObservableSortedList; import de.kuschku.util.observables.lists.ObservableSortedList;
import de.kuschku.util.observables.callbacks.wrappers.AdapterUICallbackWrapper;
import static de.kuschku.util.AndroidAssert.assertNotNull;
public class SimpleBacklogManager extends BacklogManager { public class SimpleBacklogManager extends BacklogManager {
SparseArray<ObservableSortedList<Message>> backlogs = new SparseArray<>(); @NonNull
private BusProvider busProvider; private final SparseArray<ObservableSortedList<Message>> backlogs = new SparseArray<>();
@NonNull
private final BusProvider busProvider;
public SimpleBacklogManager(BusProvider busProvider) { public SimpleBacklogManager(@NonNull BusProvider busProvider) {
this.busProvider = busProvider; this.busProvider = busProvider;
} }
...@@ -38,23 +44,29 @@ public class SimpleBacklogManager extends BacklogManager { ...@@ -38,23 +44,29 @@ public class SimpleBacklogManager extends BacklogManager {
))); )));
} }
public void receiveBacklog(int bufferId, int from, int to, int count, int extra, List<Message> messages) { public void receiveBacklog(@IntRange(from=0) int bufferId, int from, int to, int count, int extra, @NonNull List<Message> messages) {
get(bufferId).list.addAll(messages); get(bufferId).list.addAll(messages);
busProvider.sendEvent(new BacklogReceivedEvent(bufferId)); busProvider.sendEvent(new BacklogReceivedEvent(bufferId));
} }
@Override @Override
public void displayMessage(int bufferId, Message message) { public void displayMessage(@IntRange(from=0) int bufferId, @NonNull Message message) {
get(bufferId).list.add(message); ObservableSortedList<Message> messages = get(bufferId);
assertNotNull(messages);
messages.list.add(message);
} }
public void bind(int bufferId, @Nullable RecyclerView.Adapter adapter, AutoScroller scroller) { public void bind(@IntRange(from=0) int bufferId, @NonNull RecyclerView.Adapter adapter, @Nullable AutoScroller scroller) {
get(bufferId).addCallback(new AdapterUICallbackWrapper(adapter, scroller)); ObservableSortedList<Message> messages = get(bufferId);
assertNotNull(messages);
messages.addCallback(new AdapterUICallbackWrapper(adapter, scroller));
} }
@Override @Override
public void requestMoreBacklog(int bufferId, int count) { public void requestMoreBacklog(@IntRange(from=0) int bufferId, int count) {
ObservableSortedList<Message> backlog = backlogs.get(bufferId); ObservableSortedList<Message> backlog = backlogs.get(bufferId);
int messageId = int messageId =
(backlog == null) ? -1 : (backlog == null) ? -1 :
...@@ -64,15 +76,18 @@ public class SimpleBacklogManager extends BacklogManager { ...@@ -64,15 +76,18 @@ public class SimpleBacklogManager extends BacklogManager {
requestBacklog(bufferId, -1, messageId, count, 0); requestBacklog(bufferId, -1, messageId, count, 0);
} }
public ObservableSortedList<Message> get(int bufferId) { public ObservableSortedList<Message> get(@IntRange(from=0) int bufferId) {
if (backlogs.get(bufferId) == null) if (backlogs.get(bufferId) == null)
backlogs.put(bufferId, new ObservableComparableSortedList<>(Message.class, true)); backlogs.put(bufferId, new ObservableComparableSortedList<>(Message.class, true));
return backlogs.get(bufferId); ObservableSortedList<Message> messages = backlogs.get(bufferId);
assertNotNull(messages);
return messages;
} }
@Override @Override
public void init(InitDataFunction function, BusProvider provider, Client client) { public void init(@NonNull InitDataFunction function, @NonNull BusProvider provider, @NonNull Client client) {
} }
} }
package de.kuschku.libquassel.events; package de.kuschku.libquassel.events;
import android.support.annotation.IntRange;
@SuppressWarnings("WeakerAccess")
public class BacklogReceivedEvent { public class BacklogReceivedEvent {
@IntRange(from=0)
public final int bufferId; public final int bufferId;
public BacklogReceivedEvent(int bufferId) { public BacklogReceivedEvent(int bufferId) {
......
package de.kuschku.libquassel.events;
public class BufferUpdatedEvent {
public final int bufferId;
public BufferUpdatedEvent(int bufferId) {
this.bufferId = bufferId;
}
@Override
public String toString() {
return "BufferUpdatedEvent{" +
"bufferId=" + bufferId +
'}';
}
}
package de.kuschku.libquassel.events;
public class BufferViewManagerChangedEvent {
public final int id;
public final Action action;
public BufferViewManagerChangedEvent(int id, Action action) {
this.id = id;
this.action = action;
}
public enum Action {
ADD,
REMOVE,
MODIFY
}
}
package de.kuschku.libquassel.events;
public class BuffersChangedEvent {
public BuffersChangedEvent() {
}
@Override
public String toString() {
return "BuffersChangedEvent{}";
}
}
package de.kuschku.libquassel.events; package de.kuschku.libquassel.events;
import android.support.annotation.NonNull;
@SuppressWarnings("WeakerAccess")
public class ConnectionChangeEvent { public class ConnectionChangeEvent {
@NonNull
public final Status status; public final Status status;
@NonNull
public final String reason; public final String reason;
public ConnectionChangeEvent(Status status) { public ConnectionChangeEvent(@NonNull Status status) {
this(status, ""); this(status, "");
} }
public ConnectionChangeEvent(Status status, String reason) { public ConnectionChangeEvent(@NonNull Status status, @NonNull String reason) {
this.status = status; this.status = status;
this.reason = reason; this.reason = reason;
} }
@NonNull
@Override @Override
public String toString() { public String toString() {
return "ConnectionChangeEvent{" + return "ConnectionChangeEvent{" +
......
package de.kuschku.libquassel.events; package de.kuschku.libquassel.events;
import android.support.annotation.NonNull;
@SuppressWarnings("WeakerAccess")
public class CoreSetupFailedEvent { public class CoreSetupFailedEvent {
public final String reason; public final String reason;
...@@ -7,6 +10,7 @@ public class CoreSetupFailedEvent { ...@@ -7,6 +10,7 @@ public class CoreSetupFailedEvent {
this.reason = reason; this.reason = reason;
} }
@NonNull
@Override @Override
public String toString() { public String toString() {
return "CoreSetupFailedEvent{" + return "CoreSetupFailedEvent{" +
......
package de.kuschku.libquassel.events; package de.kuschku.libquassel.events;
import android.support.annotation.NonNull;
@SuppressWarnings("WeakerAccess")
public class CoreSetupSuccessfulEvent { public class CoreSetupSuccessfulEvent {
public CoreSetupSuccessfulEvent() { public CoreSetupSuccessfulEvent() {
} }
@NonNull
@Override @Override
public String toString() { public String toString() {
return "CoreSetupSuccessfulEvent{}"; return "CoreSetupSuccessfulEvent{}";
......
package de.kuschku.libquassel.events; package de.kuschku.libquassel.events;
@SuppressWarnings("WeakerAccess")
public class GeneralErrorEvent { public class GeneralErrorEvent {
public String debugInfo; public String debugInfo;
public Exception exception; public Exception exception;
......
package de.kuschku.libquassel.events; package de.kuschku.libquassel.events;
import android.support.annotation.NonNull;
@SuppressWarnings("WeakerAccess")
public class HandshakeFailedEvent { public class HandshakeFailedEvent {
public final String reason; public final String reason;
...@@ -7,6 +10,7 @@ public class HandshakeFailedEvent { ...@@ -7,6 +10,7 @@ public class HandshakeFailedEvent {
this.reason = reason; this.reason = reason;
} }
@NonNull
@Override @Override
public String toString() { public String toString() {
return "HandshakeFailedEvent{" + return "HandshakeFailedEvent{" +
......
package de.kuschku.libquassel.events; package de.kuschku.libquassel.events;
import android.support.annotation.NonNull;
@SuppressWarnings("WeakerAccess")
public class LoginFailedEvent { public class LoginFailedEvent {
public final String reason; public final String reason;
...@@ -7,6 +10,7 @@ public class LoginFailedEvent { ...@@ -7,6 +10,7 @@ public class LoginFailedEvent {
this.reason = reason; this.reason = reason;
} }
@NonNull
@Override @Override
public String toString() { public String toString() {
return "LoginFailedEvent{" + return "LoginFailedEvent{" +
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment