Commit cc94abe8 authored by Yusuke Iwaki's avatar Yusuke Iwaki

remove ServerConfig

parent b9a14855
...@@ -5,12 +5,22 @@ import android.content.Intent; ...@@ -5,12 +5,22 @@ import android.content.Intent;
import chat.rocket.android.activity.AddServerActivity; import chat.rocket.android.activity.AddServerActivity;
import chat.rocket.android.activity.LoginActivity; import chat.rocket.android.activity.LoginActivity;
import chat.rocket.android.activity.MainActivity;
/** /**
* utility class for launching Activity. * utility class for launching Activity.
*/ */
public class LaunchUtil { public class LaunchUtil {
/**
* launch MainActivity with proper flags.
*/
public static void showMainActivity(Context context) {
Intent intent = new Intent(context, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(intent);
}
/** /**
* launch AddServerActivity with proper flags. * launch AddServerActivity with proper flags.
*/ */
...@@ -23,10 +33,10 @@ public class LaunchUtil { ...@@ -23,10 +33,10 @@ public class LaunchUtil {
/** /**
* launch ServerConfigActivity with proper flags. * launch ServerConfigActivity with proper flags.
*/ */
public static void showLoginActivity(Context context, String serverCondigId) { public static void showLoginActivity(Context context, String hostname) {
Intent intent = new Intent(context, LoginActivity.class); Intent intent = new Intent(context, LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_CLEAR_TOP); intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("serverConfigId", serverCondigId); intent.putExtra("hostname", hostname);
context.startActivity(intent); context.startActivity(intent);
} }
} }
...@@ -7,8 +7,9 @@ import io.realm.Realm; ...@@ -7,8 +7,9 @@ import io.realm.Realm;
import io.realm.RealmConfiguration; import io.realm.RealmConfiguration;
import java.util.List; import java.util.List;
import chat.rocket.android.model.ServerConfig;
import chat.rocket.android.realm_helper.RealmStore; import chat.rocket.android.realm_helper.RealmStore;
import chat.rocket.android.service.ConnectivityManager;
import chat.rocket.android.service.ServerInfo;
import chat.rocket.android.wrappers.InstabugWrapper; import chat.rocket.android.wrappers.InstabugWrapper;
/** /**
...@@ -23,10 +24,9 @@ public class RocketChatApplication extends MultiDexApplication { ...@@ -23,10 +24,9 @@ public class RocketChatApplication extends MultiDexApplication {
Realm.setDefaultConfiguration( Realm.setDefaultConfiguration(
new RealmConfiguration.Builder().deleteRealmIfMigrationNeeded().build()); new RealmConfiguration.Builder().deleteRealmIfMigrationNeeded().build());
List<ServerConfig> configs = RealmStore.getDefault().executeTransactionForReadResults(realm -> List<ServerInfo> serverInfoList = ConnectivityManager.getInstance(this).getServerList();
realm.where(ServerConfig.class).isNotNull(ServerConfig.SESSION).findAll()); for (ServerInfo serverInfo : serverInfoList) {
for (ServerConfig config : configs) { RealmStore.put(serverInfo.hostname);
RealmStore.put(config.getServerConfigId());
} }
Stetho.initialize(Stetho.newInitializerBuilder(this) Stetho.initialize(Stetho.newInitializerBuilder(this)
......
...@@ -9,7 +9,7 @@ import java.util.UUID; ...@@ -9,7 +9,7 @@ import java.util.UUID;
* sharedpreference-based cache. * sharedpreference-based cache.
*/ */
public class RocketChatCache { public class RocketChatCache {
public static final String KEY_SELECTED_SERVER_CONFIG_ID = "selectedServerConfigId"; public static final String KEY_SELECTED_SERVER_HOSTNAME = "selectedServerHostname";
public static final String KEY_SELECTED_ROOM_ID = "selectedRoomId"; public static final String KEY_SELECTED_ROOM_ID = "selectedRoomId";
private static final String KEY_PUSH_ID = "pushId"; private static final String KEY_PUSH_ID = "pushId";
......
...@@ -5,61 +5,50 @@ import android.content.SharedPreferences; ...@@ -5,61 +5,50 @@ import android.content.SharedPreferences;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import chat.rocket.android.LaunchUtil;
import chat.rocket.android.RocketChatCache; import chat.rocket.android.RocketChatCache;
import chat.rocket.android.model.ServerConfig;
import chat.rocket.android.model.ddp.RoomSubscription; import chat.rocket.android.model.ddp.RoomSubscription;
import chat.rocket.android.push.PushConstants; import chat.rocket.android.push.PushConstants;
import chat.rocket.android.push.PushNotificationHandler; import chat.rocket.android.push.PushNotificationHandler;
import chat.rocket.android.realm_helper.RealmListObserver; import chat.rocket.android.realm_helper.RealmListObserver;
import chat.rocket.android.realm_helper.RealmStore; import chat.rocket.android.realm_helper.RealmStore;
import chat.rocket.android.service.RocketChatService; import chat.rocket.android.service.ConnectivityManager;
import icepick.State; import icepick.State;
abstract class AbstractAuthedActivity extends AbstractFragmentActivity { abstract class AbstractAuthedActivity extends AbstractFragmentActivity {
@State protected String serverConfigId; @State protected String hostname;
@State protected String roomId; @State protected String roomId;
SharedPreferences.OnSharedPreferenceChangeListener preferenceChangeListener = SharedPreferences.OnSharedPreferenceChangeListener preferenceChangeListener =
(sharedPreferences, key) -> { (sharedPreferences, key) -> {
if (RocketChatCache.KEY_SELECTED_SERVER_CONFIG_ID.equals(key)) { if (RocketChatCache.KEY_SELECTED_SERVER_HOSTNAME.equals(key)) {
updateServerConfigIdIfNeeded(sharedPreferences); updateHostnameIfNeeded(sharedPreferences);
} else if (RocketChatCache.KEY_SELECTED_ROOM_ID.equals(key)) { } else if (RocketChatCache.KEY_SELECTED_ROOM_ID.equals(key)) {
updateRoomIdIfNeeded(sharedPreferences); updateRoomIdIfNeeded(sharedPreferences);
} }
}; };
private RealmListObserver<ServerConfig> unconfiguredServersObserver =
RealmStore.getDefault()
.createListObserver(realm ->
realm.where(ServerConfig.class).isNotNull(ServerConfig.SESSION).findAll())
.setOnUpdateListener(results -> {
if (results.isEmpty()) {
LaunchUtil.showAddServerActivity(this);
}
});
@Override @Override
protected void onCreate(@Nullable Bundle savedInstanceState) { protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
if (savedInstanceState == null) { if (savedInstanceState == null) {
onIntent(getIntent()); handleIntent(getIntent());
} }
} }
@Override @Override
protected void onNewIntent(Intent intent) { protected void onNewIntent(Intent intent) {
super.onNewIntent(intent); super.onNewIntent(intent);
onIntent(intent); handleIntent(intent);
} }
private void onIntent(Intent intent) { private void handleIntent(Intent intent) {
if (intent == null) { if (intent == null) {
return; return;
} }
if (intent.hasExtra(PushConstants.SERVER_CONFIG_ID)) { if (intent.hasExtra(PushConstants.HOSTNAME)) {
SharedPreferences.Editor editor = RocketChatCache.get(this).edit(); SharedPreferences.Editor editor = RocketChatCache.get(this).edit();
editor.putString(RocketChatCache.KEY_SELECTED_SERVER_CONFIG_ID, editor.putString(RocketChatCache.KEY_SELECTED_SERVER_HOSTNAME,
intent.getStringExtra(PushConstants.SERVER_CONFIG_ID)); intent.getStringExtra(PushConstants.HOSTNAME));
if (intent.hasExtra(PushConstants.ROOM_ID)) { if (intent.hasExtra(PushConstants.ROOM_ID)) {
editor.putString(RocketChatCache.KEY_SELECTED_ROOM_ID, editor.putString(RocketChatCache.KEY_SELECTED_ROOM_ID,
...@@ -74,24 +63,23 @@ abstract class AbstractAuthedActivity extends AbstractFragmentActivity { ...@@ -74,24 +63,23 @@ abstract class AbstractAuthedActivity extends AbstractFragmentActivity {
} }
} }
private void updateServerConfigIdIfNeeded(SharedPreferences prefs) { private void updateHostnameIfNeeded(SharedPreferences prefs) {
String newServerConfigId = prefs.getString(RocketChatCache.KEY_SELECTED_SERVER_CONFIG_ID, null); String newHostname = prefs.getString(RocketChatCache.KEY_SELECTED_SERVER_HOSTNAME, null);
if (serverConfigId == null) { if (hostname == null) {
if (newServerConfigId != null && assertServerConfigExists(newServerConfigId, prefs)) { if (newHostname != null && assertServerRealmStoreExists(newHostname, prefs)) {
updateServerConfigId(newServerConfigId); updateHostname(newHostname);
} }
} else { } else {
if (!serverConfigId.equals(newServerConfigId) if (!hostname.equals(newHostname) && assertServerRealmStoreExists(newHostname, prefs)) {
&& assertServerConfigExists(newServerConfigId, prefs)) { updateHostname(newHostname);
updateServerConfigId(newServerConfigId);
} }
} }
} }
private boolean assertServerConfigExists(String serverConfigId, SharedPreferences prefs) { private boolean assertServerRealmStoreExists(String hostname, SharedPreferences prefs) {
if (RealmStore.get(serverConfigId) == null) { if (RealmStore.get(hostname) == null) {
prefs.edit() prefs.edit()
.remove(RocketChatCache.KEY_SELECTED_SERVER_CONFIG_ID) .remove(RocketChatCache.KEY_SELECTED_SERVER_HOSTNAME)
.remove(RocketChatCache.KEY_SELECTED_ROOM_ID) .remove(RocketChatCache.KEY_SELECTED_ROOM_ID)
.apply(); .apply();
return false; return false;
...@@ -99,9 +87,9 @@ abstract class AbstractAuthedActivity extends AbstractFragmentActivity { ...@@ -99,9 +87,9 @@ abstract class AbstractAuthedActivity extends AbstractFragmentActivity {
return true; return true;
} }
private void updateServerConfigId(String serverConfigId) { private void updateHostname(String hostname) {
this.serverConfigId = serverConfigId; this.hostname = hostname;
onServerConfigIdUpdated(); onHostnameUpdated();
} }
private void updateRoomIdIfNeeded(SharedPreferences prefs) { private void updateRoomIdIfNeeded(SharedPreferences prefs) {
...@@ -118,11 +106,11 @@ abstract class AbstractAuthedActivity extends AbstractFragmentActivity { ...@@ -118,11 +106,11 @@ abstract class AbstractAuthedActivity extends AbstractFragmentActivity {
} }
private boolean assertRoomSubscriptionExists(String roomId, SharedPreferences prefs) { private boolean assertRoomSubscriptionExists(String roomId, SharedPreferences prefs) {
if (!assertServerConfigExists(serverConfigId, prefs)) { if (!assertServerRealmStoreExists(hostname, prefs)) {
return false; return false;
} }
RoomSubscription room = RealmStore.get(serverConfigId).executeTransactionForRead(realm -> RoomSubscription room = RealmStore.get(hostname).executeTransactionForRead(realm ->
realm.where(RoomSubscription.class).equalTo(RoomSubscription.ROOM_ID, roomId).findFirst()); realm.where(RoomSubscription.class).equalTo(RoomSubscription.ROOM_ID, roomId).findFirst());
if (room == null) { if (room == null) {
prefs.edit() prefs.edit()
...@@ -138,7 +126,7 @@ abstract class AbstractAuthedActivity extends AbstractFragmentActivity { ...@@ -138,7 +126,7 @@ abstract class AbstractAuthedActivity extends AbstractFragmentActivity {
onRoomIdUpdated(); onRoomIdUpdated();
} }
protected void onServerConfigIdUpdated() { protected void onHostnameUpdated() {
} }
protected void onRoomIdUpdated() { protected void onRoomIdUpdated() {
...@@ -147,11 +135,10 @@ abstract class AbstractAuthedActivity extends AbstractFragmentActivity { ...@@ -147,11 +135,10 @@ abstract class AbstractAuthedActivity extends AbstractFragmentActivity {
@Override @Override
protected void onResume() { protected void onResume() {
super.onResume(); super.onResume();
RocketChatService.keepAlive(this); ConnectivityManager.getInstance(getApplicationContext()).keepAliveServer();
unconfiguredServersObserver.sub();
SharedPreferences prefs = RocketChatCache.get(this); SharedPreferences prefs = RocketChatCache.get(this);
updateServerConfigIdIfNeeded(prefs); updateHostnameIfNeeded(prefs);
updateRoomIdIfNeeded(prefs); updateRoomIdIfNeeded(prefs);
prefs.registerOnSharedPreferenceChangeListener(preferenceChangeListener); prefs.registerOnSharedPreferenceChangeListener(preferenceChangeListener);
} }
...@@ -161,7 +148,6 @@ abstract class AbstractAuthedActivity extends AbstractFragmentActivity { ...@@ -161,7 +148,6 @@ abstract class AbstractAuthedActivity extends AbstractFragmentActivity {
SharedPreferences prefs = RocketChatCache.get(this); SharedPreferences prefs = RocketChatCache.get(this);
prefs.unregisterOnSharedPreferenceChangeListener(preferenceChangeListener); prefs.unregisterOnSharedPreferenceChangeListener(preferenceChangeListener);
unconfiguredServersObserver.unsub();
super.onPause(); super.onPause();
} }
......
...@@ -2,72 +2,18 @@ package chat.rocket.android.activity; ...@@ -2,72 +2,18 @@ package chat.rocket.android.activity;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import java.util.UUID;
import chat.rocket.android.R; import chat.rocket.android.R;
import chat.rocket.android.RocketChatCache; import chat.rocket.android.fragment.add_server.InputHostnameFragment;
import chat.rocket.android.fragment.server_config.InputHostnameFragment;
import chat.rocket.android.fragment.server_config.WaitingFragment;
import chat.rocket.android.model.ServerConfig;
import chat.rocket.android.realm_helper.RealmListObserver;
import chat.rocket.android.realm_helper.RealmObjectObserver;
import chat.rocket.android.realm_helper.RealmStore;
public class AddServerActivity extends AbstractFragmentActivity { public class AddServerActivity extends AbstractFragmentActivity {
private String serverConfigId;
private RealmListObserver<ServerConfig> configuredServersObserver = RealmStore.getDefault()
.createListObserver(
realm -> realm.where(ServerConfig.class).isNotNull(ServerConfig.SESSION).findAll())
.setOnUpdateListener(results -> {
if (!results.isEmpty()) {
RocketChatCache.get(this).edit()
.putString(RocketChatCache.KEY_SELECTED_SERVER_CONFIG_ID, serverConfigId)
.apply();
finish();
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
}
});
private RealmObjectObserver<ServerConfig> targetServerConfigObserver = RealmStore.getDefault()
.createObjectObserver(realm ->
realm.where(ServerConfig.class).equalTo(ServerConfig.ID, serverConfigId))
.setOnUpdateListener(config -> {
if (config == null || config.getState() == ServerConfig.STATE_CONNECTION_ERROR) {
showFragment(new InputHostnameFragment());
} else {
showFragment(
WaitingFragment.create(getString(R.string.add_server_activity_waiting_server)));
}
});
@Override @Override
protected void onCreate(@Nullable Bundle savedInstanceState) { protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.simple_screen); setContentView(R.layout.simple_screen);
setupServerConfigId(); showFragment(new InputHostnameFragment());
}
private void setupServerConfigId() {
ServerConfig config = RealmStore.getDefault().executeTransactionForRead(realm ->
realm.where(ServerConfig.class).isNull(ServerConfig.HOSTNAME).findFirst());
if (config != null) {
serverConfigId = config.getServerConfigId();
return;
}
config = RealmStore.getDefault().executeTransactionForRead(realm ->
realm.where(ServerConfig.class)
.equalTo(ServerConfig.STATE, ServerConfig.STATE_CONNECTION_ERROR).findFirst());
if (config != null) {
serverConfigId = config.getServerConfigId();
return;
}
serverConfigId = UUID.randomUUID().toString();
} }
@Override @Override
...@@ -75,41 +21,6 @@ public class AddServerActivity extends AbstractFragmentActivity { ...@@ -75,41 +21,6 @@ public class AddServerActivity extends AbstractFragmentActivity {
return R.id.content; return R.id.content;
} }
@Override
protected void onResume() {
super.onResume();
configuredServersObserver.sub();
targetServerConfigObserver.sub();
}
@Override
protected void onPause() {
configuredServersObserver.unsub();
targetServerConfigObserver.unsub();
super.onPause();
}
@Override
protected void showFragment(Fragment fragment) {
injectServerConfigIdArgTo(fragment);
super.showFragment(fragment);
}
@Override
protected void showFragmentWithBackStack(Fragment fragment) {
injectServerConfigIdArgTo(fragment);
super.showFragmentWithBackStack(fragment);
}
private void injectServerConfigIdArgTo(Fragment fragment) {
Bundle args = fragment.getArguments();
if (args == null) {
args = new Bundle();
}
args.putString(ServerConfig.ID, serverConfigId);
fragment.setArguments(args);
}
@Override @Override
protected void onBackPressedNotHandled() { protected void onBackPressedNotHandled() {
moveTaskToBack(true); moveTaskToBack(true);
......
...@@ -7,14 +7,13 @@ import android.support.v4.app.Fragment; ...@@ -7,14 +7,13 @@ import android.support.v4.app.Fragment;
import chat.rocket.android.R; import chat.rocket.android.R;
import chat.rocket.android.fragment.server_config.LoginFragment; import chat.rocket.android.fragment.server_config.LoginFragment;
import chat.rocket.android.fragment.server_config.RetryConnectFragment;
import chat.rocket.android.fragment.server_config.RetryLoginFragment; import chat.rocket.android.fragment.server_config.RetryLoginFragment;
import chat.rocket.android.fragment.server_config.WaitingFragment; import chat.rocket.android.fragment.server_config.WaitingFragment;
import chat.rocket.android.helper.TextUtils; import chat.rocket.android.helper.TextUtils;
import chat.rocket.android.model.ServerConfig;
import chat.rocket.android.model.internal.Session; import chat.rocket.android.model.internal.Session;
import chat.rocket.android.realm_helper.RealmObjectObserver; import chat.rocket.android.realm_helper.RealmObjectObserver;
import chat.rocket.android.realm_helper.RealmStore; import chat.rocket.android.realm_helper.RealmStore;
import chat.rocket.android.service.ConnectivityManager;
import chat.rocket.android.service.RocketChatService; import chat.rocket.android.service.RocketChatService;
/** /**
...@@ -22,8 +21,7 @@ import chat.rocket.android.service.RocketChatService; ...@@ -22,8 +21,7 @@ import chat.rocket.android.service.RocketChatService;
*/ */
public class LoginActivity extends AbstractFragmentActivity { public class LoginActivity extends AbstractFragmentActivity {
private String serverConfigId; private String hostname;
private RealmObjectObserver<ServerConfig> serverConfigErrorObserver;
private RealmObjectObserver<Session> sessionObserver; private RealmObjectObserver<Session> sessionObserver;
@Override @Override
...@@ -41,50 +39,33 @@ public class LoginActivity extends AbstractFragmentActivity { ...@@ -41,50 +39,33 @@ public class LoginActivity extends AbstractFragmentActivity {
return; return;
} }
serverConfigId = intent.getStringExtra(ServerConfig.ID); hostname = intent.getStringExtra("hostname");
if (TextUtils.isEmpty(serverConfigId)) { if (TextUtils.isEmpty(hostname)) {
finish(); finish();
return; return;
} }
serverConfigErrorObserver = RealmStore.getDefault() sessionObserver = RealmStore.get(hostname)
.createObjectObserver(realm ->
realm.where(ServerConfig.class)
.equalTo(ServerConfig.ID, serverConfigId)
.equalTo(ServerConfig.STATE, ServerConfig.STATE_CONNECTION_ERROR))
.setOnUpdateListener(this::onRenderServerConfigError);
sessionObserver = RealmStore.get(serverConfigId)
.createObjectObserver(Session::queryDefaultSession) .createObjectObserver(Session::queryDefaultSession)
.setOnUpdateListener(this::onRenderServerConfigSession); .setOnUpdateListener(this::onRenderServerConfigSession);
setContentView(R.layout.simple_screen); setContentView(R.layout.simple_screen);
showFragment(new WaitingFragment()); showFragment(new WaitingFragment());
serverConfigErrorObserver.sub();
} }
@Override @Override
protected void onResume() { protected void onResume() {
super.onResume(); super.onResume();
RocketChatService.keepAlive(this); ConnectivityManager.getInstance(getApplicationContext()).keepAliveServer();
sessionObserver.sub();
} }
@Override @Override
protected void onDestroy() { protected void onDestroy() {
sessionObserver.unsub(); sessionObserver.unsub();
serverConfigErrorObserver.unsub();
super.onDestroy(); super.onDestroy();
} }
private void onRenderServerConfigError(ServerConfig config) {
if (config != null) {
sessionObserver.unsub();
showFragment(new RetryConnectFragment());
} else {
sessionObserver.sub();
}
}
private void onRenderServerConfigSession(Session session) { private void onRenderServerConfigSession(Session session) {
if (session == null) { if (session == null) {
showFragment(new LoginFragment()); showFragment(new LoginFragment());
...@@ -107,22 +88,22 @@ public class LoginActivity extends AbstractFragmentActivity { ...@@ -107,22 +88,22 @@ public class LoginActivity extends AbstractFragmentActivity {
@Override @Override
protected void showFragment(Fragment fragment) { protected void showFragment(Fragment fragment) {
injectServerConfigIdArgTo(fragment); injectHostnameArgTo(fragment);
super.showFragment(fragment); super.showFragment(fragment);
} }
@Override @Override
protected void showFragmentWithBackStack(Fragment fragment) { protected void showFragmentWithBackStack(Fragment fragment) {
injectServerConfigIdArgTo(fragment); injectHostnameArgTo(fragment);
super.showFragmentWithBackStack(fragment); super.showFragmentWithBackStack(fragment);
} }
private void injectServerConfigIdArgTo(Fragment fragment) { private void injectHostnameArgTo(Fragment fragment) {
Bundle args = fragment.getArguments(); Bundle args = fragment.getArguments();
if (args == null) { if (args == null) {
args = new Bundle(); args = new Bundle();
} }
args.putString(ServerConfig.ID, serverConfigId); args.putString("hostname", hostname);
fragment.setArguments(args); fragment.setArguments(args);
} }
......
...@@ -17,7 +17,6 @@ import chat.rocket.android.fragment.chatroom.RoomFragment; ...@@ -17,7 +17,6 @@ import chat.rocket.android.fragment.chatroom.RoomFragment;
import chat.rocket.android.fragment.sidebar.SidebarMainFragment; import chat.rocket.android.fragment.sidebar.SidebarMainFragment;
import chat.rocket.android.helper.LogcatIfError; import chat.rocket.android.helper.LogcatIfError;
import chat.rocket.android.helper.TextUtils; import chat.rocket.android.helper.TextUtils;
import chat.rocket.android.model.ServerConfig;
import chat.rocket.android.model.ddp.RoomSubscription; import chat.rocket.android.model.ddp.RoomSubscription;
import chat.rocket.android.model.ddp.User; import chat.rocket.android.model.ddp.User;
import chat.rocket.android.model.internal.Session; import chat.rocket.android.model.internal.Session;
...@@ -25,6 +24,7 @@ import chat.rocket.android.realm_helper.RealmHelper; ...@@ -25,6 +24,7 @@ import chat.rocket.android.realm_helper.RealmHelper;
import chat.rocket.android.realm_helper.RealmListObserver; import chat.rocket.android.realm_helper.RealmListObserver;
import chat.rocket.android.realm_helper.RealmObjectObserver; import chat.rocket.android.realm_helper.RealmObjectObserver;
import chat.rocket.android.realm_helper.RealmStore; import chat.rocket.android.realm_helper.RealmStore;
import chat.rocket.android.service.ConnectivityManager;
import chat.rocket.android.widget.RoomToolbar; import chat.rocket.android.widget.RoomToolbar;
import hugo.weaving.DebugLog; import hugo.weaving.DebugLog;
...@@ -53,6 +53,10 @@ public class MainActivity extends AbstractAuthedActivity { ...@@ -53,6 +53,10 @@ public class MainActivity extends AbstractAuthedActivity {
if (roomId == null) { if (roomId == null) {
showFragment(new HomeFragment()); showFragment(new HomeFragment());
} }
if (shouldLaunchAddServerActivity()) {
LaunchUtil.showAddServerActivity(this);
}
} }
@Override @Override
...@@ -82,15 +86,15 @@ public class MainActivity extends AbstractAuthedActivity { ...@@ -82,15 +86,15 @@ public class MainActivity extends AbstractAuthedActivity {
} }
private void setUserOnlineIfServerAvailable() { private void setUserOnlineIfServerAvailable() {
if (serverConfigId != null) { if (hostname != null) {
new MethodCallHelper(this, serverConfigId).setUserPresence(User.STATUS_ONLINE) new MethodCallHelper(this, hostname).setUserPresence(User.STATUS_ONLINE)
.continueWith(new LogcatIfError()); .continueWith(new LogcatIfError());
} }
} }
private void setUserAwayIfServerAvailable() { private void setUserAwayIfServerAvailable() {
if (serverConfigId != null) { if (hostname != null) {
new MethodCallHelper(this, serverConfigId).setUserPresence(User.STATUS_AWAY) new MethodCallHelper(this, hostname).setUserPresence(User.STATUS_AWAY)
.continueWith(new LogcatIfError()); .continueWith(new LogcatIfError());
} }
} }
...@@ -150,10 +154,14 @@ public class MainActivity extends AbstractAuthedActivity { ...@@ -150,10 +154,14 @@ public class MainActivity extends AbstractAuthedActivity {
return false; return false;
} }
private boolean shouldLaunchAddServerActivity() {
return ConnectivityManager.getInstance(getApplicationContext()).getServerList().isEmpty();
}
@DebugLog @DebugLog
@Override @Override
protected void onServerConfigIdUpdated() { protected void onHostnameUpdated() {
super.onServerConfigIdUpdated(); super.onHostnameUpdated();
updateSessionObserver(); updateSessionObserver();
updateUnreadRoomSubscriptionObserver(); updateUnreadRoomSubscriptionObserver();
updateSidebarMainFragment(); updateSidebarMainFragment();
...@@ -165,11 +173,11 @@ public class MainActivity extends AbstractAuthedActivity { ...@@ -165,11 +173,11 @@ public class MainActivity extends AbstractAuthedActivity {
sessionObserver = null; sessionObserver = null;
} }
if (serverConfigId == null) { if (hostname == null) {
return; return;
} }
RealmHelper realmHelper = RealmStore.get(serverConfigId); RealmHelper realmHelper = RealmStore.get(hostname);
if (realmHelper == null) { if (realmHelper == null) {
return; return;
} }
...@@ -185,7 +193,7 @@ public class MainActivity extends AbstractAuthedActivity { ...@@ -185,7 +193,7 @@ public class MainActivity extends AbstractAuthedActivity {
private void onSessionChanged(@Nullable Session session) { private void onSessionChanged(@Nullable Session session) {
if (session == null) { if (session == null) {
if (isForeground) { if (isForeground) {
LaunchUtil.showLoginActivity(this, serverConfigId); LaunchUtil.showLoginActivity(this, hostname);
} }
statusTicker.updateStatus(StatusTicker.STATUS_DISMISS, null); statusTicker.updateStatus(StatusTicker.STATUS_DISMISS, null);
} else if (!TextUtils.isEmpty(session.getError())) { } else if (!TextUtils.isEmpty(session.getError())) {
...@@ -193,17 +201,8 @@ public class MainActivity extends AbstractAuthedActivity { ...@@ -193,17 +201,8 @@ public class MainActivity extends AbstractAuthedActivity {
Snackbar.make(findViewById(getLayoutContainerForFragment()), Snackbar.make(findViewById(getLayoutContainerForFragment()),
R.string.fragment_retry_login_error_title, Snackbar.LENGTH_INDEFINITE) R.string.fragment_retry_login_error_title, Snackbar.LENGTH_INDEFINITE)
.setAction(R.string.fragment_retry_login_retry_title, view -> .setAction(R.string.fragment_retry_login_retry_title, view ->
RealmStore.getDefault() ConnectivityManager.getInstance(getApplicationContext())
.executeTransaction(realm -> { .connect(hostname).subscribe()));
ServerConfig config = realm.where(ServerConfig.class)
.equalTo(ServerConfig.ID, serverConfigId).findFirst();
if (config != null
&& config.getState() == ServerConfig.STATE_CONNECTION_ERROR) {
config.setState(ServerConfig.STATE_READY);
}
return null;
}).continueWith(new LogcatIfError())));
} else if (!session.isTokenVerified()) { } else if (!session.isTokenVerified()) {
statusTicker.updateStatus(StatusTicker.STATUS_TOKEN_LOGIN, statusTicker.updateStatus(StatusTicker.STATUS_TOKEN_LOGIN,
Snackbar.make(findViewById(getLayoutContainerForFragment()), Snackbar.make(findViewById(getLayoutContainerForFragment()),
...@@ -219,11 +218,11 @@ public class MainActivity extends AbstractAuthedActivity { ...@@ -219,11 +218,11 @@ public class MainActivity extends AbstractAuthedActivity {
unreadRoomSubscriptionObserver = null; unreadRoomSubscriptionObserver = null;
} }
if (serverConfigId == null) { if (hostname == null) {
return; return;
} }
RealmHelper realmHelper = RealmStore.get(serverConfigId); RealmHelper realmHelper = RealmStore.get(hostname);
if (realmHelper == null) { if (realmHelper == null) {
return; return;
} }
...@@ -253,7 +252,7 @@ public class MainActivity extends AbstractAuthedActivity { ...@@ -253,7 +252,7 @@ public class MainActivity extends AbstractAuthedActivity {
private void updateSidebarMainFragment() { private void updateSidebarMainFragment() {
getSupportFragmentManager().beginTransaction() getSupportFragmentManager().beginTransaction()
.replace(R.id.sidebar_fragment_container, SidebarMainFragment.create(serverConfigId)) .replace(R.id.sidebar_fragment_container, SidebarMainFragment.create(hostname))
.commit(); .commit();
} }
...@@ -261,8 +260,8 @@ public class MainActivity extends AbstractAuthedActivity { ...@@ -261,8 +260,8 @@ public class MainActivity extends AbstractAuthedActivity {
protected void onRoomIdUpdated() { protected void onRoomIdUpdated() {
super.onRoomIdUpdated(); super.onRoomIdUpdated();
if (roomId != null && RoomFragment.canCreate(RealmStore.get(serverConfigId))) { if (roomId != null && RoomFragment.canCreate(RealmStore.get(hostname))) {
showFragment(RoomFragment.create(serverConfigId, roomId)); showFragment(RoomFragment.create(hostname, roomId));
closeSidebarIfNeeded(); closeSidebarIfNeeded();
} else { } else {
showFragment(new HomeFragment()); showFragment(new HomeFragment());
......
...@@ -121,10 +121,10 @@ public class DDPClientWrapper { ...@@ -121,10 +121,10 @@ public class DDPClientWrapper {
return ddpClient.ping(pingId) return ddpClient.ping(pingId)
.continueWithTask(task -> { .continueWithTask(task -> {
if (task.isFaulted()) { if (task.isFaulted()) {
RCLog.d("ping[%s] xxx failed xxx", pingId); RCLog.d(task.getError(), "ping[%s] xxx failed xxx", pingId);
return Task.forError(task.getError()); return Task.forError(task.getError());
} else { } else {
RCLog.d("pong[%s] <"); RCLog.d("pong[%s] <", pingId);
return Task.forResult(null); return Task.forResult(null);
} }
}); });
......
...@@ -12,8 +12,8 @@ import chat.rocket.android.realm_helper.RealmHelper; ...@@ -12,8 +12,8 @@ import chat.rocket.android.realm_helper.RealmHelper;
* MethodCall for uploading file. * MethodCall for uploading file.
*/ */
public class FileUploadingHelper extends MethodCallHelper { public class FileUploadingHelper extends MethodCallHelper {
public FileUploadingHelper(Context context, String serverConfigId) { public FileUploadingHelper(Context context, String hostname) {
super(context, serverConfigId); super(context, hostname);
} }
public FileUploadingHelper(RealmHelper realmHelper, DDPClientWrapper ddpClient) { public FileUploadingHelper(RealmHelper realmHelper, DDPClientWrapper ddpClient) {
......
...@@ -39,11 +39,11 @@ public class MethodCallHelper { ...@@ -39,11 +39,11 @@ public class MethodCallHelper {
protected final DDPClientWrapper ddpClient; protected final DDPClientWrapper ddpClient;
/** /**
* initialize with Context and ServerConfigId. * initialize with Context and hostname.
*/ */
public MethodCallHelper(Context context, String serverConfigId) { public MethodCallHelper(Context context, String hostname) {
this.context = context; this.context = context;
this.realmHelper = RealmStore.get(serverConfigId); this.realmHelper = RealmStore.get(hostname);
ddpClient = null; ddpClient = null;
} }
......
...@@ -10,8 +10,8 @@ import bolts.Task; ...@@ -10,8 +10,8 @@ import bolts.Task;
import chat.rocket.android.realm_helper.RealmHelper; import chat.rocket.android.realm_helper.RealmHelper;
public class RaixPushHelper extends MethodCallHelper { public class RaixPushHelper extends MethodCallHelper {
public RaixPushHelper(Context context, String serverConfigId) { public RaixPushHelper(Context context, String hostname) {
super(context, serverConfigId); super(context, hostname);
} }
public RaixPushHelper(RealmHelper realmHelper, public RaixPushHelper(RealmHelper realmHelper,
......
package chat.rocket.android.fragment.server_config; package chat.rocket.android.fragment.add_server;
import android.support.design.widget.Snackbar; import android.support.design.widget.Snackbar;
import android.widget.TextView; import android.widget.TextView;
import org.json.JSONObject;
import chat.rocket.android.BuildConfig; import chat.rocket.android.BuildConfig;
import chat.rocket.android.LaunchUtil;
import chat.rocket.android.R; import chat.rocket.android.R;
import chat.rocket.android.RocketChatCache; import chat.rocket.android.RocketChatCache;
import chat.rocket.android.api.rest.DefaultServerPolicyApi; import chat.rocket.android.api.rest.DefaultServerPolicyApi;
import chat.rocket.android.api.rest.ServerPolicyApi; import chat.rocket.android.api.rest.ServerPolicyApi;
import chat.rocket.android.helper.LogcatIfError; import chat.rocket.android.fragment.AbstractFragment;
import chat.rocket.android.helper.OkHttpHelper; import chat.rocket.android.helper.OkHttpHelper;
import chat.rocket.android.helper.ServerPolicyApiValidationHelper; import chat.rocket.android.helper.ServerPolicyApiValidationHelper;
import chat.rocket.android.helper.ServerPolicyHelper; import chat.rocket.android.helper.ServerPolicyHelper;
import chat.rocket.android.helper.TextUtils; import chat.rocket.android.helper.TextUtils;
import chat.rocket.android.model.ServerConfig; import chat.rocket.android.service.ConnectivityManager;
import chat.rocket.android.realm_helper.RealmObjectObserver; import chat.rocket.android.service.ConnectivityManagerApi;
import chat.rocket.android.realm_helper.RealmStore;
import rx.Subscription; import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers; import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers; import rx.schedulers.Schedulers;
...@@ -24,12 +23,7 @@ import rx.schedulers.Schedulers; ...@@ -24,12 +23,7 @@ import rx.schedulers.Schedulers;
/** /**
* Input server host. * Input server host.
*/ */
public class InputHostnameFragment extends AbstractServerConfigFragment { public class InputHostnameFragment extends AbstractFragment {
RealmObjectObserver<ServerConfig> serverConfigObserver = RealmStore.getDefault()
.createObjectObserver(realm ->
realm.where(ServerConfig.class).equalTo(ServerConfig.ID, serverConfigId))
.setOnUpdateListener(this::onRenderServerConfig);
Subscription serverPolicySubscription; Subscription serverPolicySubscription;
public InputHostnameFragment() { public InputHostnameFragment() {
...@@ -45,8 +39,6 @@ public class InputHostnameFragment extends AbstractServerConfigFragment { ...@@ -45,8 +39,6 @@ public class InputHostnameFragment extends AbstractServerConfigFragment {
setupVersionInfo(); setupVersionInfo();
rootView.findViewById(R.id.btn_connect).setOnClickListener(view -> handleConnect()); rootView.findViewById(R.id.btn_connect).setOnClickListener(view -> handleConnect());
serverConfigObserver.sub();
} }
private void setupVersionInfo() { private void setupVersionInfo() {
...@@ -67,9 +59,12 @@ public class InputHostnameFragment extends AbstractServerConfigFragment { ...@@ -67,9 +59,12 @@ public class InputHostnameFragment extends AbstractServerConfigFragment {
serverPolicySubscription.unsubscribe(); serverPolicySubscription.unsubscribe();
} }
rootView.findViewById(R.id.btn_connect).setEnabled(false);
serverPolicySubscription = ServerPolicyHelper.isApiVersionValid(validationHelper) serverPolicySubscription = ServerPolicyHelper.isApiVersionValid(validationHelper)
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.doOnTerminate(() -> rootView.findViewById(R.id.btn_connect).setEnabled(true))
.subscribe( .subscribe(
serverValidation -> { serverValidation -> {
if (serverValidation.isValid()) { if (serverValidation.isValid()) {
...@@ -85,7 +80,6 @@ public class InputHostnameFragment extends AbstractServerConfigFragment { ...@@ -85,7 +80,6 @@ public class InputHostnameFragment extends AbstractServerConfigFragment {
@Override @Override
public void onDestroyView() { public void onDestroyView() {
serverConfigObserver.unsub();
if (serverPolicySubscription != null) { if (serverPolicySubscription != null) {
serverPolicySubscription.unsubscribe(); serverPolicySubscription.unsubscribe();
} }
...@@ -100,36 +94,19 @@ public class InputHostnameFragment extends AbstractServerConfigFragment { ...@@ -100,36 +94,19 @@ public class InputHostnameFragment extends AbstractServerConfigFragment {
private void onServerValid(final String hostname, boolean usesSecureConnection) { private void onServerValid(final String hostname, boolean usesSecureConnection) {
RocketChatCache.get(getContext()).edit() RocketChatCache.get(getContext()).edit()
.putString(RocketChatCache.KEY_SELECTED_SERVER_CONFIG_ID, serverConfigId) .putString(RocketChatCache.KEY_SELECTED_SERVER_HOSTNAME, hostname)
.apply(); .apply();
RealmStore.getDefault().executeTransaction( ConnectivityManagerApi connectivityManager =
realm -> realm.createOrUpdateObjectFromJson(ServerConfig.class, ConnectivityManager.getInstance(getContext().getApplicationContext());
new JSONObject().put(ServerConfig.ID, serverConfigId) connectivityManager.addOrUpdateServer(hostname, hostname, !usesSecureConnection);
.put(ServerConfig.HOSTNAME, hostname) connectivityManager.keepAliveServer();
.put(ServerConfig.ERROR, JSONObject.NULL)
.put(ServerConfig.SESSION, JSONObject.NULL) LaunchUtil.showMainActivity(getContext());
.put(ServerConfig.SECURE_CONNECTION, usesSecureConnection) getActivity().overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
.put(ServerConfig.STATE, ServerConfig.STATE_READY)))
.continueWith(new LogcatIfError());
} }
private void showError(String errString) { private void showError(String errString) {
Snackbar.make(rootView, errString, Snackbar.LENGTH_LONG).show(); Snackbar.make(rootView, errString, Snackbar.LENGTH_LONG).show();
} }
private void onRenderServerConfig(ServerConfig config) {
if (config == null) {
return;
}
final TextView editor = (TextView) rootView.findViewById(R.id.editor_hostname);
if (!TextUtils.isEmpty(config.getHostname())) {
editor.setText(config.getHostname());
}
if (!TextUtils.isEmpty(config.getError())) {
showError(config.getError());
}
}
} }
...@@ -34,9 +34,9 @@ import chat.rocket.android.helper.OnBackPressListener; ...@@ -34,9 +34,9 @@ import chat.rocket.android.helper.OnBackPressListener;
import chat.rocket.android.helper.RecyclerViewAutoScrollManager; import chat.rocket.android.helper.RecyclerViewAutoScrollManager;
import chat.rocket.android.helper.RecyclerViewScrolledToBottomListener; import chat.rocket.android.helper.RecyclerViewScrolledToBottomListener;
import chat.rocket.android.helper.TextUtils; import chat.rocket.android.helper.TextUtils;
import chat.rocket.android.layouthelper.chatroom.AbstractNewMessageIndicatorManager;
import chat.rocket.android.layouthelper.chatroom.MessageFormManager; import chat.rocket.android.layouthelper.chatroom.MessageFormManager;
import chat.rocket.android.layouthelper.chatroom.MessageListAdapter; import chat.rocket.android.layouthelper.chatroom.MessageListAdapter;
import chat.rocket.android.layouthelper.chatroom.AbstractNewMessageIndicatorManager;
import chat.rocket.android.layouthelper.chatroom.PairedMessage; import chat.rocket.android.layouthelper.chatroom.PairedMessage;
import chat.rocket.android.layouthelper.extra_action.AbstractExtraActionItem; import chat.rocket.android.layouthelper.extra_action.AbstractExtraActionItem;
import chat.rocket.android.layouthelper.extra_action.MessageExtraActionBehavior; import chat.rocket.android.layouthelper.extra_action.MessageExtraActionBehavior;
...@@ -45,7 +45,6 @@ import chat.rocket.android.layouthelper.extra_action.upload.AudioUploadActionIte ...@@ -45,7 +45,6 @@ import chat.rocket.android.layouthelper.extra_action.upload.AudioUploadActionIte
import chat.rocket.android.layouthelper.extra_action.upload.ImageUploadActionItem; import chat.rocket.android.layouthelper.extra_action.upload.ImageUploadActionItem;
import chat.rocket.android.layouthelper.extra_action.upload.VideoUploadActionItem; import chat.rocket.android.layouthelper.extra_action.upload.VideoUploadActionItem;
import chat.rocket.android.log.RCLog; import chat.rocket.android.log.RCLog;
import chat.rocket.android.model.ServerConfig;
import chat.rocket.android.model.SyncState; import chat.rocket.android.model.SyncState;
import chat.rocket.android.model.ddp.Message; import chat.rocket.android.model.ddp.Message;
import chat.rocket.android.model.ddp.RoomSubscription; import chat.rocket.android.model.ddp.RoomSubscription;
...@@ -56,7 +55,7 @@ import chat.rocket.android.realm_helper.RealmHelper; ...@@ -56,7 +55,7 @@ import chat.rocket.android.realm_helper.RealmHelper;
import chat.rocket.android.realm_helper.RealmModelListAdapter; import chat.rocket.android.realm_helper.RealmModelListAdapter;
import chat.rocket.android.realm_helper.RealmObjectObserver; import chat.rocket.android.realm_helper.RealmObjectObserver;
import chat.rocket.android.realm_helper.RealmStore; import chat.rocket.android.realm_helper.RealmStore;
import chat.rocket.android.service.RocketChatService; import chat.rocket.android.service.ConnectivityManager;
import chat.rocket.android.widget.internal.ExtraActionPickerDialogFragment; import chat.rocket.android.widget.internal.ExtraActionPickerDialogFragment;
import chat.rocket.android.widget.message.MessageFormLayout; import chat.rocket.android.widget.message.MessageFormLayout;
import permissions.dispatcher.NeedsPermission; import permissions.dispatcher.NeedsPermission;
...@@ -72,11 +71,10 @@ public class RoomFragment extends AbstractChatRoomFragment ...@@ -72,11 +71,10 @@ public class RoomFragment extends AbstractChatRoomFragment
private static final int DIALOG_ID = 1; private static final int DIALOG_ID = 1;
private String serverConfigId; private String hostname;
private RealmHelper realmHelper; private RealmHelper realmHelper;
private String roomId; private String roomId;
private RealmObjectObserver<RoomSubscription> roomObserver; private RealmObjectObserver<RoomSubscription> roomObserver;
private String hostname;
private String userId; private String userId;
private String token; private String token;
private LoadMoreScrollListener scrollListener; private LoadMoreScrollListener scrollListener;
...@@ -103,9 +101,9 @@ public class RoomFragment extends AbstractChatRoomFragment ...@@ -103,9 +101,9 @@ public class RoomFragment extends AbstractChatRoomFragment
/** /**
* create fragment with roomId. * create fragment with roomId.
*/ */
public static RoomFragment create(String serverConfigId, String roomId) { public static RoomFragment create(String hostname, String roomId) {
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putString("serverConfigId", serverConfigId); args.putString("hostname", hostname);
args.putString("roomId", roomId); args.putString("roomId", roomId);
RoomFragment fragment = new RoomFragment(); RoomFragment fragment = new RoomFragment();
fragment.setArguments(args); fragment.setArguments(args);
...@@ -117,14 +115,9 @@ public class RoomFragment extends AbstractChatRoomFragment ...@@ -117,14 +115,9 @@ public class RoomFragment extends AbstractChatRoomFragment
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Bundle args = getArguments(); Bundle args = getArguments();
serverConfigId = args.getString("serverConfigId"); hostname = args.getString("hostname");
realmHelper = RealmStore.get(serverConfigId); realmHelper = RealmStore.get(hostname);
roomId = args.getString("roomId"); roomId = args.getString("roomId");
hostname = RealmStore.getDefault().executeTransactionForRead(realm ->
realm.where(ServerConfig.class)
.equalTo(ServerConfig.ID, serverConfigId)
.isNotNull(ServerConfig.HOSTNAME)
.findFirst()).getHostname();
userId = realmHelper.executeTransactionForRead(realm -> userId = realmHelper.executeTransactionForRead(realm ->
User.queryCurrentUser(realm).findFirst()).getId(); User.queryCurrentUser(realm).findFirst()).getId();
token = realmHelper.executeTransactionForRead(realm -> token = realmHelper.executeTransactionForRead(realm ->
...@@ -281,7 +274,7 @@ public class RoomFragment extends AbstractChatRoomFragment ...@@ -281,7 +274,7 @@ public class RoomFragment extends AbstractChatRoomFragment
private void setupSideMenu() { private void setupSideMenu() {
View sideMenu = rootView.findViewById(R.id.room_side_menu); View sideMenu = rootView.findViewById(R.id.room_side_menu);
sideMenu.findViewById(R.id.btn_users).setOnClickListener(view -> { sideMenu.findViewById(R.id.btn_users).setOnClickListener(view -> {
UsersOfRoomDialogFragment.create(serverConfigId, roomId, hostname) UsersOfRoomDialogFragment.create(roomId, hostname)
.show(getFragmentManager(), UsersOfRoomDialogFragment.class.getSimpleName()); .show(getFragmentManager(), UsersOfRoomDialogFragment.class.getSimpleName());
closeSideMenuIfNeeded(); closeSideMenuIfNeeded();
}); });
...@@ -347,7 +340,7 @@ public class RoomFragment extends AbstractChatRoomFragment ...@@ -347,7 +340,7 @@ public class RoomFragment extends AbstractChatRoomFragment
String uplId = new FileUploadHelper(getContext(), realmHelper) String uplId = new FileUploadHelper(getContext(), realmHelper)
.requestUploading(roomId, data.getData()); .requestUploading(roomId, data.getData());
if (!TextUtils.isEmpty(uplId)) { if (!TextUtils.isEmpty(uplId)) {
FileUploadProgressDialogFragment.create(serverConfigId, roomId, uplId) FileUploadProgressDialogFragment.create(hostname, roomId, uplId)
.show(getFragmentManager(), FileUploadProgressDialogFragment.class.getSimpleName()); .show(getFragmentManager(), FileUploadProgressDialogFragment.class.getSimpleName());
} else { } else {
// show error. // show error.
...@@ -406,7 +399,8 @@ public class RoomFragment extends AbstractChatRoomFragment ...@@ -406,7 +399,8 @@ public class RoomFragment extends AbstractChatRoomFragment
.put(LoadMessageProcedure.RESET, true)); .put(LoadMessageProcedure.RESET, true));
return null; return null;
}).onSuccessTask(task -> { }).onSuccessTask(task -> {
RocketChatService.keepAlive(getContext()); ConnectivityManager.getInstance(getContext().getApplicationContext())
.keepAliveServer();
return task; return task;
}).continueWith(new LogcatIfError()); }).continueWith(new LogcatIfError());
} }
...@@ -427,7 +421,8 @@ public class RoomFragment extends AbstractChatRoomFragment ...@@ -427,7 +421,8 @@ public class RoomFragment extends AbstractChatRoomFragment
} }
return null; return null;
}).onSuccessTask(task -> { }).onSuccessTask(task -> {
RocketChatService.keepAlive(getContext()); ConnectivityManager.getInstance(getContext().getApplicationContext())
.keepAliveServer();
return task; return task;
}).continueWith(new LogcatIfError()); }).continueWith(new LogcatIfError());
} }
...@@ -436,7 +431,7 @@ public class RoomFragment extends AbstractChatRoomFragment ...@@ -436,7 +431,7 @@ public class RoomFragment extends AbstractChatRoomFragment
RoomSubscription room = realmHelper.executeTransactionForRead(realm -> RoomSubscription room = realmHelper.executeTransactionForRead(realm ->
realm.where(RoomSubscription.class).equalTo(RoomSubscription.ROOM_ID, roomId).findFirst()); realm.where(RoomSubscription.class).equalTo(RoomSubscription.ROOM_ID, roomId).findFirst());
if (room != null && room.isAlert()) { if (room != null && room.isAlert()) {
new MethodCallHelper(getContext(), serverConfigId).readMessages(roomId) new MethodCallHelper(getContext(), hostname).readMessages(roomId)
.continueWith(new LogcatIfError()); .continueWith(new LogcatIfError());
} }
} }
......
...@@ -31,8 +31,8 @@ abstract class AbstractChatRoomDialogFragment extends BottomSheetDialogFragment ...@@ -31,8 +31,8 @@ abstract class AbstractChatRoomDialogFragment extends BottomSheetDialogFragment
} }
protected void handleArgs(@NonNull Bundle args) { protected void handleArgs(@NonNull Bundle args) {
String serverConfigId = args.getString("serverConfigId"); String hostname = args.getString("hostname");
realmHelper = RealmStore.get(serverConfigId); realmHelper = RealmStore.get(hostname);
roomId = args.getString("roomId"); roomId = args.getString("roomId");
} }
......
...@@ -25,10 +25,10 @@ public class FileUploadProgressDialogFragment extends AbstractChatRoomDialogFrag ...@@ -25,10 +25,10 @@ public class FileUploadProgressDialogFragment extends AbstractChatRoomDialogFrag
public FileUploadProgressDialogFragment() { public FileUploadProgressDialogFragment() {
} }
public static FileUploadProgressDialogFragment create(String serverConfigId, public static FileUploadProgressDialogFragment create(String hostname,
String roomId, String uplId) { String roomId, String uplId) {
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putString("serverConfigId", serverConfigId); args.putString("hostname", hostname);
args.putString("roomId", roomId); args.putString("roomId", roomId);
args.putString("uplId", uplId); args.putString("uplId", uplId);
......
...@@ -20,7 +20,7 @@ import chat.rocket.android.log.RCLog; ...@@ -20,7 +20,7 @@ import chat.rocket.android.log.RCLog;
import chat.rocket.android.model.SyncState; import chat.rocket.android.model.SyncState;
import chat.rocket.android.model.internal.GetUsersOfRoomsProcedure; import chat.rocket.android.model.internal.GetUsersOfRoomsProcedure;
import chat.rocket.android.realm_helper.RealmObjectObserver; import chat.rocket.android.realm_helper.RealmObjectObserver;
import chat.rocket.android.service.RocketChatService; import chat.rocket.android.service.ConnectivityManager;
/** /**
* Dialog to show members in a room. * Dialog to show members in a room.
...@@ -37,12 +37,10 @@ public class UsersOfRoomDialogFragment extends AbstractChatRoomDialogFragment { ...@@ -37,12 +37,10 @@ public class UsersOfRoomDialogFragment extends AbstractChatRoomDialogFragment {
/** /**
* create UsersOfRoomDialogFragment with required parameters. * create UsersOfRoomDialogFragment with required parameters.
*/ */
public static UsersOfRoomDialogFragment create(String serverConfigId, public static UsersOfRoomDialogFragment create(String roomId, String hostname) {
String roomId, String hostname) {
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putString("serverConfigId", serverConfigId);
args.putString("roomId", roomId);
args.putString("hostname", hostname); args.putString("hostname", hostname);
args.putString("roomId", roomId);
UsersOfRoomDialogFragment fragment = new UsersOfRoomDialogFragment(); UsersOfRoomDialogFragment fragment = new UsersOfRoomDialogFragment();
fragment.setArguments(args); fragment.setArguments(args);
...@@ -91,7 +89,8 @@ public class UsersOfRoomDialogFragment extends AbstractChatRoomDialogFragment { ...@@ -91,7 +89,8 @@ public class UsersOfRoomDialogFragment extends AbstractChatRoomDialogFragment {
.put("showAll", true)); .put("showAll", true));
return null; return null;
}).onSuccessTask(task -> { }).onSuccessTask(task -> {
RocketChatService.keepAlive(getContext()); ConnectivityManager.getInstance(getContext().getApplicationContext())
.keepAliveServer();
return task; return task;
}).continueWith(new LogcatIfError()); }).continueWith(new LogcatIfError());
} }
......
...@@ -14,13 +14,11 @@ import chat.rocket.android.api.MethodCallHelper; ...@@ -14,13 +14,11 @@ import chat.rocket.android.api.MethodCallHelper;
import chat.rocket.android.fragment.AbstractWebViewFragment; import chat.rocket.android.fragment.AbstractWebViewFragment;
import chat.rocket.android.helper.LogcatIfError; import chat.rocket.android.helper.LogcatIfError;
import chat.rocket.android.log.RCLog; import chat.rocket.android.log.RCLog;
import chat.rocket.android.model.ServerConfig;
import chat.rocket.android.model.ddp.MeteorLoginServiceConfiguration; import chat.rocket.android.model.ddp.MeteorLoginServiceConfiguration;
import chat.rocket.android.realm_helper.RealmStore; import chat.rocket.android.realm_helper.RealmStore;
public abstract class AbstractOAuthFragment extends AbstractWebViewFragment { public abstract class AbstractOAuthFragment extends AbstractWebViewFragment {
protected String serverConfigId;
protected String hostname; protected String hostname;
private String url; private String url;
private boolean resultOK; private boolean resultOK;
...@@ -31,7 +29,7 @@ public abstract class AbstractOAuthFragment extends AbstractWebViewFragment { ...@@ -31,7 +29,7 @@ public abstract class AbstractOAuthFragment extends AbstractWebViewFragment {
private boolean hasValidArgs(Bundle args) { private boolean hasValidArgs(Bundle args) {
return args != null return args != null
&& args.containsKey("serverConfigId"); && args.containsKey("hostname");
} }
protected final String getStateString() { protected final String getStateString() {
...@@ -52,22 +50,19 @@ public abstract class AbstractOAuthFragment extends AbstractWebViewFragment { ...@@ -52,22 +50,19 @@ public abstract class AbstractOAuthFragment extends AbstractWebViewFragment {
Bundle args = getArguments(); Bundle args = getArguments();
if (!hasValidArgs(args)) { if (!hasValidArgs(args)) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"serverConfigId required"); "hostname required");
} }
serverConfigId = args.getString("serverConfigId"); hostname = args.getString("hostname");
ServerConfig serverConfig = RealmStore.getDefault().executeTransactionForRead(realm ->
realm.where(ServerConfig.class).equalTo(ServerConfig.ID, serverConfigId).findFirst());
MeteorLoginServiceConfiguration oauthConfig = MeteorLoginServiceConfiguration oauthConfig =
RealmStore.get(serverConfigId).executeTransactionForRead(realm -> RealmStore.get(hostname).executeTransactionForRead(realm ->
realm.where(MeteorLoginServiceConfiguration.class) realm.where(MeteorLoginServiceConfiguration.class)
.equalTo(MeteorLoginServiceConfiguration.SERVICE, getOAuthServiceName()) .equalTo(MeteorLoginServiceConfiguration.SERVICE, getOAuthServiceName())
.findFirst()); .findFirst());
if (serverConfig == null || oauthConfig == null) { if (oauthConfig == null) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Invalid serverConfigId given,"); "Invalid hostname given,");
} }
hostname = serverConfig.getHostname();
url = generateURL(oauthConfig); url = generateURL(oauthConfig);
} }
...@@ -114,7 +109,7 @@ public abstract class AbstractOAuthFragment extends AbstractWebViewFragment { ...@@ -114,7 +109,7 @@ public abstract class AbstractOAuthFragment extends AbstractWebViewFragment {
} }
private void handleOAuthCallback(final String credentialToken, final String credentialSecret) { private void handleOAuthCallback(final String credentialToken, final String credentialSecret) {
new MethodCallHelper(getContext(), serverConfigId) new MethodCallHelper(getContext(), hostname)
.loginWithOAuth(credentialToken, credentialSecret) .loginWithOAuth(credentialToken, credentialSecret)
.continueWith(new LogcatIfError()); .continueWith(new LogcatIfError());
} }
......
...@@ -9,7 +9,7 @@ import chat.rocket.android.fragment.AbstractFragment; ...@@ -9,7 +9,7 @@ import chat.rocket.android.fragment.AbstractFragment;
import chat.rocket.android.helper.TextUtils; import chat.rocket.android.helper.TextUtils;
abstract class AbstractServerConfigFragment extends AbstractFragment { abstract class AbstractServerConfigFragment extends AbstractFragment {
protected String serverConfigId; protected String hostname;
@Override @Override
public void onCreate(@Nullable Bundle savedInstanceState) { public void onCreate(@Nullable Bundle savedInstanceState) {
...@@ -21,8 +21,8 @@ abstract class AbstractServerConfigFragment extends AbstractFragment { ...@@ -21,8 +21,8 @@ abstract class AbstractServerConfigFragment extends AbstractFragment {
return; return;
} }
serverConfigId = args.getString("serverConfigId"); hostname = args.getString("hostname");
if (TextUtils.isEmpty(serverConfigId)) { if (TextUtils.isEmpty(hostname)) {
finish(); finish();
return; return;
} }
......
...@@ -32,7 +32,7 @@ public class LoginFragment extends AbstractServerConfigFragment { ...@@ -32,7 +32,7 @@ public class LoginFragment extends AbstractServerConfigFragment {
@Override @Override
public void onCreate(@Nullable Bundle savedInstanceState) { public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
authProvidersObserver = RealmStore.get(serverConfigId) authProvidersObserver = RealmStore.get(hostname)
.createListObserver(realm -> realm.where(MeteorLoginServiceConfiguration.class).findAll()) .createListObserver(realm -> realm.where(MeteorLoginServiceConfiguration.class).findAll())
.setOnUpdateListener(this::onRenderAuthProviders); .setOnUpdateListener(this::onRenderAuthProviders);
} }
...@@ -52,7 +52,7 @@ public class LoginFragment extends AbstractServerConfigFragment { ...@@ -52,7 +52,7 @@ public class LoginFragment extends AbstractServerConfigFragment {
view.setEnabled(false); view.setEnabled(false);
waitingView.setVisibility(View.VISIBLE); waitingView.setVisibility(View.VISIBLE);
new MethodCallHelper(getContext(), serverConfigId) new MethodCallHelper(getContext(), hostname)
.loginWithEmail(username.toString(), passwd.toString()) .loginWithEmail(username.toString(), passwd.toString())
.continueWith(task -> { .continueWith(task -> {
if (task.isFaulted()) { if (task.isFaulted()) {
...@@ -65,7 +65,7 @@ public class LoginFragment extends AbstractServerConfigFragment { ...@@ -65,7 +65,7 @@ public class LoginFragment extends AbstractServerConfigFragment {
}); });
final View btnUserRegistration = rootView.findViewById(R.id.btn_user_registration); final View btnUserRegistration = rootView.findViewById(R.id.btn_user_registration);
btnUserRegistration.setOnClickListener(view -> UserRegistrationDialogFragment.create(serverConfigId, btnUserRegistration.setOnClickListener(view -> UserRegistrationDialogFragment.create(hostname,
txtUsername.getText().toString(), txtPasswd.getText().toString()) txtUsername.getText().toString(), txtPasswd.getText().toString())
.show(getFragmentManager(), UserRegistrationDialogFragment.class.getSimpleName())); .show(getFragmentManager(), UserRegistrationDialogFragment.class.getSimpleName()));
} }
...@@ -96,7 +96,7 @@ public class LoginFragment extends AbstractServerConfigFragment { ...@@ -96,7 +96,7 @@ public class LoginFragment extends AbstractServerConfigFragment {
} }
if (fragment != null) { if (fragment != null) {
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putString("serverConfigId", serverConfigId); args.putString("hostname", hostname);
fragment.setArguments(args); fragment.setArguments(args);
showFragmentWithBackStack(fragment); showFragmentWithBackStack(fragment);
} }
......
package chat.rocket.android.fragment.server_config;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.View;
import android.widget.TextView;
import chat.rocket.android.R;
import chat.rocket.android.helper.LogcatIfError;
import chat.rocket.android.helper.TextUtils;
import chat.rocket.android.model.ServerConfig;
import chat.rocket.android.realm_helper.RealmObjectObserver;
import chat.rocket.android.realm_helper.RealmStore;
/**
* Login screen.
*/
public class RetryConnectFragment extends AbstractServerConfigFragment {
private RealmObjectObserver<ServerConfig> serverConfigObserver;
@Override
protected int getLayout() {
return R.layout.fragment_retry_login;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
serverConfigObserver = RealmStore.getDefault()
.createObjectObserver(realm ->
realm.where(ServerConfig.class).equalTo(ServerConfig.ID, serverConfigId))
.setOnUpdateListener(this::onRenderServerConfig);
}
@Override
protected void onSetupView() {
rootView.findViewById(R.id.waiting).setVisibility(View.GONE);
final View btnRetry = rootView.findViewById(R.id.btn_retry_login);
btnRetry.setOnClickListener(view -> {
RealmStore.getDefault()
.executeTransaction(realm -> {
ServerConfig config = realm.where(ServerConfig.class)
.equalTo(ServerConfig.ID, serverConfigId).findFirst();
if (config != null && config.getState() == ServerConfig.STATE_CONNECTION_ERROR) {
config.setState(ServerConfig.STATE_READY);
}
return null;
}).continueWith(new LogcatIfError());
});
}
private void onRenderServerConfig(ServerConfig config) {
if (config == null) {
return;
}
final String error = config.getError();
final TextView txtError = (TextView) rootView.findViewById(R.id.txt_error_description);
if (!TextUtils.isEmpty(error)) {
txtError.setText(error);
}
final int state = config.getState();
if (state == ServerConfig.STATE_CONNECTED) {
finish();
}
rootView.findViewById(R.id.btn_retry_login)
.setEnabled(state == ServerConfig.STATE_CONNECTION_ERROR);
}
@Override
public void onResume() {
super.onResume();
serverConfigObserver.sub();
}
@Override
public void onPause() {
serverConfigObserver.unsub();
super.onPause();
}
}
...@@ -26,7 +26,7 @@ public class RetryLoginFragment extends AbstractServerConfigFragment { ...@@ -26,7 +26,7 @@ public class RetryLoginFragment extends AbstractServerConfigFragment {
@Override @Override
public void onCreate(@Nullable Bundle savedInstanceState) { public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
sessionObserver = RealmStore.get(serverConfigId) sessionObserver = RealmStore.get(hostname)
.createObjectObserver(Session::queryDefaultSession) .createObjectObserver(Session::queryDefaultSession)
.setOnUpdateListener(this::onRenderServerConfigSession); .setOnUpdateListener(this::onRenderServerConfigSession);
} }
...@@ -49,7 +49,7 @@ public class RetryLoginFragment extends AbstractServerConfigFragment { ...@@ -49,7 +49,7 @@ public class RetryLoginFragment extends AbstractServerConfigFragment {
view.setEnabled(false); view.setEnabled(false);
waitingView.setVisibility(View.VISIBLE); waitingView.setVisibility(View.VISIBLE);
new MethodCallHelper(getContext(), serverConfigId).loginWithToken(token) new MethodCallHelper(getContext(), hostname).loginWithToken(token)
.continueWith(task -> { .continueWith(task -> {
if (task.isFaulted()) { if (task.isFaulted()) {
view.setEnabled(true); view.setEnabled(true);
......
...@@ -20,7 +20,7 @@ import chat.rocket.android.helper.TextUtils; ...@@ -20,7 +20,7 @@ import chat.rocket.android.helper.TextUtils;
* Dialog for user registration. * Dialog for user registration.
*/ */
public class UserRegistrationDialogFragment extends DialogFragment { public class UserRegistrationDialogFragment extends DialogFragment {
private String serverConfigId; private String hostname;
private String username; private String username;
private String email; private String email;
private String password; private String password;
...@@ -32,23 +32,23 @@ public class UserRegistrationDialogFragment extends DialogFragment { ...@@ -32,23 +32,23 @@ public class UserRegistrationDialogFragment extends DialogFragment {
/** /**
* create UserRegistrationDialogFragment with auto-detect email/username. * create UserRegistrationDialogFragment with auto-detect email/username.
*/ */
public static UserRegistrationDialogFragment create(String serverConfigId, public static UserRegistrationDialogFragment create(String hostname,
String usernameOrEmail, String password) { String usernameOrEmail, String password) {
if (Patterns.EMAIL_ADDRESS.matcher(usernameOrEmail).matches()) { if (Patterns.EMAIL_ADDRESS.matcher(usernameOrEmail).matches()) {
return create(serverConfigId, null, usernameOrEmail, password); return create(hostname, null, usernameOrEmail, password);
} else { } else {
return create(serverConfigId, usernameOrEmail, null, password); return create(hostname, usernameOrEmail, null, password);
} }
} }
/** /**
* create UserRegistrationDialogFragment. * create UserRegistrationDialogFragment.
*/ */
public static UserRegistrationDialogFragment create(String serverConfigId, public static UserRegistrationDialogFragment create(String hostname,
String username, String email, String username, String email,
String password) { String password) {
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putString("serverConfigId", serverConfigId); args.putString("hostname", hostname);
if (!TextUtils.isEmpty(username)) { if (!TextUtils.isEmpty(username)) {
args.putString("username", username); args.putString("username", username);
} }
...@@ -69,7 +69,7 @@ public class UserRegistrationDialogFragment extends DialogFragment { ...@@ -69,7 +69,7 @@ public class UserRegistrationDialogFragment extends DialogFragment {
Bundle args = getArguments(); Bundle args = getArguments();
if (args != null) { if (args != null) {
serverConfigId = args.getString("serverConfigId"); hostname = args.getString("hostname");
username = args.getString("username"); username = args.getString("username");
email = args.getString("email"); email = args.getString("email");
password = args.getString("password"); password = args.getString("password");
...@@ -113,7 +113,7 @@ public class UserRegistrationDialogFragment extends DialogFragment { ...@@ -113,7 +113,7 @@ public class UserRegistrationDialogFragment extends DialogFragment {
email = txtEmail.getText().toString(); email = txtEmail.getText().toString();
password = txtPasswd.getText().toString(); password = txtPasswd.getText().toString();
MethodCallHelper methodCallHelper = new MethodCallHelper(getContext(), serverConfigId); MethodCallHelper methodCallHelper = new MethodCallHelper(getContext(), hostname);
methodCallHelper.registerUser(username, email, password, password) methodCallHelper.registerUser(username, email, password, password)
.onSuccessTask(task -> methodCallHelper.loginWithEmail(email, password)) .onSuccessTask(task -> methodCallHelper.loginWithEmail(email, password))
.onSuccessTask(task -> methodCallHelper.setUsername(username)) //TODO: should prompt! .onSuccessTask(task -> methodCallHelper.setUsername(username)) //TODO: should prompt!
......
...@@ -7,6 +7,8 @@ import android.widget.CompoundButton; ...@@ -7,6 +7,8 @@ import android.widget.CompoundButton;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import com.jakewharton.rxbinding.view.RxView;
import com.jakewharton.rxbinding.widget.RxCompoundButton;
import chat.rocket.android.BuildConfig; import chat.rocket.android.BuildConfig;
import chat.rocket.android.R; import chat.rocket.android.R;
...@@ -14,12 +16,11 @@ import chat.rocket.android.RocketChatCache; ...@@ -14,12 +16,11 @@ import chat.rocket.android.RocketChatCache;
import chat.rocket.android.api.MethodCallHelper; import chat.rocket.android.api.MethodCallHelper;
import chat.rocket.android.fragment.AbstractFragment; import chat.rocket.android.fragment.AbstractFragment;
import chat.rocket.android.fragment.sidebar.dialog.AbstractAddRoomDialogFragment; import chat.rocket.android.fragment.sidebar.dialog.AbstractAddRoomDialogFragment;
import chat.rocket.android.fragment.sidebar.dialog.AddDirectMessageDialogFragment;
import chat.rocket.android.fragment.sidebar.dialog.AddChannelDialogFragment; import chat.rocket.android.fragment.sidebar.dialog.AddChannelDialogFragment;
import chat.rocket.android.fragment.sidebar.dialog.AddDirectMessageDialogFragment;
import chat.rocket.android.helper.LogcatIfError; import chat.rocket.android.helper.LogcatIfError;
import chat.rocket.android.helper.TextUtils; import chat.rocket.android.helper.TextUtils;
import chat.rocket.android.layouthelper.chatroom.RoomListManager; import chat.rocket.android.layouthelper.chatroom.RoomListManager;
import chat.rocket.android.model.ServerConfig;
import chat.rocket.android.model.ddp.RoomSubscription; import chat.rocket.android.model.ddp.RoomSubscription;
import chat.rocket.android.model.ddp.User; import chat.rocket.android.model.ddp.User;
import chat.rocket.android.realm_helper.RealmHelper; import chat.rocket.android.realm_helper.RealmHelper;
...@@ -28,14 +29,10 @@ import chat.rocket.android.realm_helper.RealmObjectObserver; ...@@ -28,14 +29,10 @@ import chat.rocket.android.realm_helper.RealmObjectObserver;
import chat.rocket.android.realm_helper.RealmStore; import chat.rocket.android.realm_helper.RealmStore;
import chat.rocket.android.renderer.UserRenderer; import chat.rocket.android.renderer.UserRenderer;
import com.jakewharton.rxbinding.view.RxView;
import com.jakewharton.rxbinding.widget.RxCompoundButton;
public class SidebarMainFragment extends AbstractFragment { public class SidebarMainFragment extends AbstractFragment {
private String serverConfigId;
private RoomListManager roomListManager;
private String hostname; private String hostname;
private RoomListManager roomListManager;
private RealmListObserver<RoomSubscription> roomsObserver; private RealmListObserver<RoomSubscription> roomsObserver;
private RealmObjectObserver<User> currentUserObserver; private RealmObjectObserver<User> currentUserObserver;
private MethodCallHelper methodCallHelper; private MethodCallHelper methodCallHelper;
...@@ -44,11 +41,11 @@ public class SidebarMainFragment extends AbstractFragment { ...@@ -44,11 +41,11 @@ public class SidebarMainFragment extends AbstractFragment {
} }
/** /**
* create SidebarMainFragment with serverConfigId. * create SidebarMainFragment with hostname.
*/ */
public static SidebarMainFragment create(String serverConfigId) { public static SidebarMainFragment create(String hostname) {
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putString("serverConfigId", serverConfigId); args.putString("hostname", hostname);
SidebarMainFragment fragment = new SidebarMainFragment(); SidebarMainFragment fragment = new SidebarMainFragment();
fragment.setArguments(args); fragment.setArguments(args);
...@@ -60,15 +57,9 @@ public class SidebarMainFragment extends AbstractFragment { ...@@ -60,15 +57,9 @@ public class SidebarMainFragment extends AbstractFragment {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Bundle args = getArguments(); Bundle args = getArguments();
serverConfigId = args == null ? null : args.getString("serverConfigId"); hostname = args == null ? null : args.getString("hostname");
if (!TextUtils.isEmpty(serverConfigId)) { if (!TextUtils.isEmpty(hostname)) {
ServerConfig config = RealmStore.getDefault().executeTransactionForRead(realm -> RealmHelper realmHelper = RealmStore.get(hostname);
realm.where(ServerConfig.class).equalTo(ServerConfig.ID, serverConfigId).findFirst());
if (config != null) {
hostname = config.getHostname();
}
RealmHelper realmHelper = RealmStore.get(serverConfigId);
if (realmHelper != null) { if (realmHelper != null) {
roomsObserver = realmHelper roomsObserver = realmHelper
.createListObserver( .createListObserver(
...@@ -80,14 +71,14 @@ public class SidebarMainFragment extends AbstractFragment { ...@@ -80,14 +71,14 @@ public class SidebarMainFragment extends AbstractFragment {
.createObjectObserver(User::queryCurrentUser) .createObjectObserver(User::queryCurrentUser)
.setOnUpdateListener(this::onCurrentUser); .setOnUpdateListener(this::onCurrentUser);
methodCallHelper = new MethodCallHelper(getContext(), serverConfigId); methodCallHelper = new MethodCallHelper(getContext(), hostname);
} }
} }
} }
@Override @Override
protected int getLayout() { protected int getLayout() {
if (serverConfigId == null) { if (hostname == null) {
return R.layout.simple_screen; return R.layout.simple_screen;
} else { } else {
return R.layout.fragment_sidebar_main; return R.layout.fragment_sidebar_main;
...@@ -96,7 +87,7 @@ public class SidebarMainFragment extends AbstractFragment { ...@@ -96,7 +87,7 @@ public class SidebarMainFragment extends AbstractFragment {
@Override @Override
protected void onSetupView() { protected void onSetupView() {
if (serverConfigId == null) { if (hostname == null) {
return; return;
} }
...@@ -203,7 +194,6 @@ public class SidebarMainFragment extends AbstractFragment { ...@@ -203,7 +194,6 @@ public class SidebarMainFragment extends AbstractFragment {
private void showAddRoomDialog(DialogFragment dialog) { private void showAddRoomDialog(DialogFragment dialog) {
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putString("serverConfigId", serverConfigId);
args.putString("hostname", hostname); args.putString("hostname", hostname);
dialog.setArguments(args); dialog.setArguments(args);
dialog.show(getFragmentManager(), AbstractAddRoomDialogFragment.class.getSimpleName()); dialog.show(getFragmentManager(), AbstractAddRoomDialogFragment.class.getSimpleName());
......
...@@ -38,10 +38,9 @@ public abstract class AbstractAddRoomDialogFragment extends RxAppCompatDialogFra ...@@ -38,10 +38,9 @@ public abstract class AbstractAddRoomDialogFragment extends RxAppCompatDialogFra
} }
protected void handleArgs(@NonNull Bundle args) { protected void handleArgs(@NonNull Bundle args) {
String serverConfigId = args.getString("serverConfigId");
realmHelper = RealmStore.get(serverConfigId);
methodCall = new MethodCallHelper(getContext(), serverConfigId);
hostname = args.getString("hostname"); hostname = args.getString("hostname");
realmHelper = RealmStore.get(hostname);
methodCall = new MethodCallHelper(getContext(), hostname);
} }
@Override @Override
......
package chat.rocket.android.helper;
import java.util.concurrent.TimeUnit;
import rx.Observable;
import rx.Single;
import rx.functions.Func0;
import rx.functions.Func1;
/**
* Rx operator and so on.
*/
public class RxHelper {
public static Func1<Observable<? extends Throwable>, Observable<?>> exponentialBackoff(
int maxRetryCount, long base, TimeUnit unit) {
return errors -> errors
.zipWith(Observable.range(0, maxRetryCount), (error, retryCount) -> retryCount)
.flatMap(retryCount -> Observable.timer(base * (long) Math.pow(2, retryCount), unit));
}
public static <T> Single<T> lazy(Func0<Single<T>> func) {
return Single.just(true).flatMap(_junk -> func.call());
}
}
...@@ -13,10 +13,10 @@ public class ServerPolicyApiValidationHelper { ...@@ -13,10 +13,10 @@ public class ServerPolicyApiValidationHelper {
this.serverPolicyApi = serverPolicyApi; this.serverPolicyApi = serverPolicyApi;
} }
public Observable<ServerPolicyHelper.ServerInfo> getApiVersion() { public Observable<ServerPolicyHelper.ServerInfoResponse> getApiVersion() {
return serverPolicyApi.getApiInfoSecurely() return serverPolicyApi.getApiInfoSecurely()
.onErrorResumeNext(serverPolicyApi.getApiInfoInsecurely()) .onErrorResumeNext(serverPolicyApi.getApiInfoInsecurely())
.map(response -> new ServerPolicyHelper.ServerInfo( .map(response -> new ServerPolicyHelper.ServerInfoResponse(
response.getProtocol().equals(ServerPolicyApi.SECURE_PROTOCOL), response.getProtocol().equals(ServerPolicyApi.SECURE_PROTOCOL),
response.getData() response.getData()
)); ));
......
...@@ -72,11 +72,11 @@ public class ServerPolicyHelper { ...@@ -72,11 +72,11 @@ public class ServerPolicyHelper {
return versionParts.length >= 3 && Integer.parseInt(versionParts[1]) >= 49; return versionParts.length >= 3 && Integer.parseInt(versionParts[1]) >= 49;
} }
public static class ServerInfo { public static class ServerInfoResponse {
private final boolean secureConnection; private final boolean secureConnection;
private final JSONObject apiInfo; private final JSONObject apiInfo;
public ServerInfo(boolean secureConnection, JSONObject apiInfo) { public ServerInfoResponse(boolean secureConnection, JSONObject apiInfo) {
this.secureConnection = secureConnection; this.secureConnection = secureConnection;
this.apiInfo = apiInfo; this.apiInfo = apiInfo;
} }
......
package chat.rocket.android.model;
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
/**
* Server configuration.
*/
@Deprecated
public class ServerConfig extends RealmObject {
@SuppressWarnings({"PMD.ShortVariable"})
public static final String ID = "serverConfigId";
public static final String HOSTNAME = "hostname";
public static final String STATE = "state";
public static final String SESSION = "session";
public static final String SECURE_CONNECTION = "secureConnection";
public static final String ERROR = "error";
public static final int STATE_READY = 0;
public static final int STATE_CONNECTING = 1;
public static final int STATE_CONNECTED = 2;
public static final int STATE_CONNECTION_ERROR = 3;
@PrimaryKey private String serverConfigId;
private String hostname;
private int state;
private String session;
private boolean secureConnection;
private String error;
public String getServerConfigId() {
return serverConfigId;
}
public void setServerConfigId(String serverConfigId) {
this.serverConfigId = serverConfigId;
}
public String getHostname() {
return hostname;
}
public void setHostname(String hostname) {
this.hostname = hostname;
}
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
public String getSession() {
return session;
}
public void setSession(String session) {
this.session = session;
}
public boolean usesSecureConnection() {
return secureConnection;
}
public void setSecureConnection(boolean usesSecureConnection) {
this.secureConnection = usesSecureConnection;
}
public String getError() {
return error;
}
public void setError(String error) {
this.error = error;
}
}
...@@ -16,7 +16,7 @@ import chat.rocket.android.log.RCLog; ...@@ -16,7 +16,7 @@ import chat.rocket.android.log.RCLog;
import chat.rocket.android.model.SyncState; import chat.rocket.android.model.SyncState;
import chat.rocket.android.realm_helper.RealmHelper; import chat.rocket.android.realm_helper.RealmHelper;
import chat.rocket.android.realm_helper.RealmObjectObserver; import chat.rocket.android.realm_helper.RealmObjectObserver;
import chat.rocket.android.service.RocketChatService; import chat.rocket.android.service.ConnectivityManager;
public class MethodCall extends RealmObject { public class MethodCall extends RealmObject {
...@@ -89,7 +89,8 @@ public class MethodCall extends RealmObject { ...@@ -89,7 +89,8 @@ public class MethodCall extends RealmObject {
REF_MAP.put(newId, observer); REF_MAP.put(newId, observer);
if (context != null) { if (context != null) {
RocketChatService.keepAlive(context); ConnectivityManager.getInstance(context.getApplicationContext())
.keepAliveServer();
} }
} }
return null; return null;
......
...@@ -70,6 +70,6 @@ public interface PushConstants { ...@@ -70,6 +70,6 @@ public interface PushConstants {
String FORCE_START = "force-start"; String FORCE_START = "force-start";
// RC specific constants // RC specific constants
String SERVER_CONFIG_ID = "serverConfigId"; String HOSTNAME = "hostname";
String ROOM_ID = "roomId"; String ROOM_ID = "roomId";
} }
\ No newline at end of file
...@@ -20,7 +20,6 @@ import android.support.v4.util.SparseArrayCompat; ...@@ -20,7 +20,6 @@ import android.support.v4.util.SparseArrayCompat;
import android.text.Html; import android.text.Html;
import android.text.Spanned; import android.text.Spanned;
import android.util.Log; import android.util.Log;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
...@@ -32,7 +31,6 @@ import java.net.URL; ...@@ -32,7 +31,6 @@ import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Random; import java.util.Random;
import chat.rocket.android.activity.MainActivity; import chat.rocket.android.activity.MainActivity;
import chat.rocket.android.push.interactors.PushInteractor;
public class PushNotificationHandler implements PushConstants { public class PushNotificationHandler implements PushConstants {
...@@ -64,8 +62,7 @@ public class PushNotificationHandler implements PushConstants { ...@@ -64,8 +62,7 @@ public class PushNotificationHandler implements PushConstants {
return messageMap.get(notId); return messageMap.get(notId);
} }
public void showNotificationIfPossible(Context context, PushInteractor pushInteractor, public void showNotificationIfPossible(Context context, Bundle extras) {
Bundle extras) {
// Send a notification if there is a message or title, otherwise just send data // Send a notification if there is a message or title, otherwise just send data
String message = extras.getString(MESSAGE); String message = extras.getString(MESSAGE);
...@@ -87,26 +84,21 @@ public class PushNotificationHandler implements PushConstants { ...@@ -87,26 +84,21 @@ public class PushNotificationHandler implements PushConstants {
extras.putString(TITLE, getAppName(context)); extras.putString(TITLE, getAppName(context));
} }
createNotification(context, pushInteractor, extras); createNotification(context, extras);
} }
} }
public void createNotification(Context context, PushInteractor pushInteractor, Bundle extras) { public void createNotification(Context context, Bundle extras) {
NotificationManager mNotificationManager = NotificationManager mNotificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
String appName = getAppName(context); String appName = getAppName(context);
String packageName = context.getPackageName(); String packageName = context.getPackageName();
Resources resources = context.getResources(); Resources resources = context.getResources();
String serverUrl = getServerUrl(extras); String hostname = getHostname(extras);
String roomId = getRoomId(extras); String roomId = getRoomId(extras);
if (serverUrl == null || roomId == null) { if (hostname == null || roomId == null) {
return;
}
String serverConfigId = pushInteractor.getServerConfigId(serverUrl);
if (serverConfigId == null) {
return; return;
} }
...@@ -114,7 +106,7 @@ public class PushNotificationHandler implements PushConstants { ...@@ -114,7 +106,7 @@ public class PushNotificationHandler implements PushConstants {
Intent notificationIntent = new Intent(context, MainActivity.class); Intent notificationIntent = new Intent(context, MainActivity.class);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP); notificationIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
notificationIntent.putExtra(PUSH_BUNDLE, extras); notificationIntent.putExtra(PUSH_BUNDLE, extras);
notificationIntent.putExtra(SERVER_CONFIG_ID, serverConfigId); notificationIntent.putExtra(HOSTNAME, hostname);
notificationIntent.putExtra(ROOM_ID, roomId); notificationIntent.putExtra(ROOM_ID, roomId);
notificationIntent.putExtra(NOT_ID, notId); notificationIntent.putExtra(NOT_ID, notId);
...@@ -634,7 +626,7 @@ public class PushNotificationHandler implements PushConstants { ...@@ -634,7 +626,7 @@ public class PushNotificationHandler implements PushConstants {
return count; return count;
} }
private String getServerUrl(Bundle extras) { private String getHostname(Bundle extras) {
try { try {
JSONObject jsonObject = new JSONObject(extras.getString("ejson", "[]")); JSONObject jsonObject = new JSONObject(extras.getString("ejson", "[]"));
if (!jsonObject.has("host")) { if (!jsonObject.has("host")) {
......
...@@ -15,8 +15,6 @@ import java.util.ArrayList; ...@@ -15,8 +15,6 @@ import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import chat.rocket.android.push.PushConstants; import chat.rocket.android.push.PushConstants;
import chat.rocket.android.push.PushNotificationHandler; import chat.rocket.android.push.PushNotificationHandler;
import chat.rocket.android.push.interactors.DefaultPushInteractor;
import chat.rocket.android.push.interactors.PushInteractor;
@SuppressLint("NewApi") @SuppressLint("NewApi")
public class GCMIntentService extends GcmListenerService implements PushConstants { public class GCMIntentService extends GcmListenerService implements PushConstants {
...@@ -33,13 +31,11 @@ public class GCMIntentService extends GcmListenerService implements PushConstant ...@@ -33,13 +31,11 @@ public class GCMIntentService extends GcmListenerService implements PushConstant
Context applicationContext = getApplicationContext(); Context applicationContext = getApplicationContext();
PushInteractor pushInteractor = new DefaultPushInteractor();
extras = normalizeExtras(applicationContext, extras); extras = normalizeExtras(applicationContext, extras);
PushNotificationHandler pushNotificationHandler = new PushNotificationHandler(); PushNotificationHandler pushNotificationHandler = new PushNotificationHandler();
pushNotificationHandler.showNotificationIfPossible(applicationContext, pushInteractor, extras); pushNotificationHandler.showNotificationIfPossible(applicationContext, extras);
} }
/* /*
......
...@@ -4,24 +4,21 @@ import com.google.android.gms.iid.InstanceIDListenerService; ...@@ -4,24 +4,21 @@ import com.google.android.gms.iid.InstanceIDListenerService;
import java.util.List; import java.util.List;
import chat.rocket.android.helper.GcmPushSettingHelper; import chat.rocket.android.helper.GcmPushSettingHelper;
import chat.rocket.android.model.ServerConfig;
import chat.rocket.android.model.ddp.PublicSetting; import chat.rocket.android.model.ddp.PublicSetting;
import chat.rocket.android.model.internal.GcmPushRegistration; import chat.rocket.android.model.internal.GcmPushRegistration;
import chat.rocket.android.realm_helper.RealmHelper; import chat.rocket.android.realm_helper.RealmHelper;
import chat.rocket.android.realm_helper.RealmStore; import chat.rocket.android.realm_helper.RealmStore;
import chat.rocket.android.service.ConnectivityManager;
import chat.rocket.android.service.ServerInfo;
public class GcmInstanceIDListenerService extends InstanceIDListenerService { public class GcmInstanceIDListenerService extends InstanceIDListenerService {
@Override @Override
public void onTokenRefresh() { public void onTokenRefresh() {
List<ServerConfig> serverConfigs = RealmStore.getDefault() List<ServerInfo> serverInfoList = ConnectivityManager.getInstance(getApplicationContext())
.executeTransactionForReadResults(realm -> .getServerList();
realm.where(ServerConfig.class) for (ServerInfo serverInfo : serverInfoList) {
.isNotNull(ServerConfig.ID) RealmHelper realmHelper = RealmStore.get(serverInfo.hostname);
.isNotNull(ServerConfig.HOSTNAME)
.findAll());
for (ServerConfig serverConfig : serverConfigs) {
RealmHelper realmHelper = RealmStore.get(serverConfig.getServerConfigId());
if (realmHelper != null) { if (realmHelper != null) {
updateGcmToken(realmHelper); updateGcmToken(realmHelper);
} }
......
package chat.rocket.android.push.interactors;
import chat.rocket.android.helper.ServerPolicyHelper;
import chat.rocket.android.model.ServerConfig;
import chat.rocket.android.realm_helper.RealmStore;
public class DefaultPushInteractor implements PushInteractor {
@Override
public String getServerConfigId(String hostname) {
final ServerConfig serverConfig = RealmStore.getDefault()
.executeTransactionForRead(
realm -> realm.where(ServerConfig.class)
.equalTo(ServerConfig.HOSTNAME, ServerPolicyHelper.enforceHostname(hostname))
.findFirst());
return serverConfig != null ? serverConfig.getServerConfigId() : "";
}
}
package chat.rocket.android.push.interactors;
public interface PushInteractor {
String getServerConfigId(String hostname);
}
...@@ -3,8 +3,8 @@ package chat.rocket.android.service; ...@@ -3,8 +3,8 @@ package chat.rocket.android.service;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import java.util.List; import java.util.List;
import rx.Completable;
import rx.Observable; import rx.Observable;
import rx.Single;
/** /**
* interfaces used for Activity/Fragment and other UI-related logic. * interfaces used for Activity/Fragment and other UI-related logic.
...@@ -12,11 +12,11 @@ import rx.Observable; ...@@ -12,11 +12,11 @@ import rx.Observable;
public interface ConnectivityManagerApi { public interface ConnectivityManagerApi {
void keepAliveServer(); void keepAliveServer();
void addOrUpdateServer(String hostname, @Nullable String name); void addOrUpdateServer(String hostname, @Nullable String name, boolean insecure);
void removeServer(String hostname); void removeServer(String hostname);
Completable connect(String hostname); Single<Boolean> connect(String hostname);
List<ServerInfo> getServerList(); List<ServerInfo> getServerList();
......
...@@ -10,15 +10,18 @@ import java.util.ArrayList; ...@@ -10,15 +10,18 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import rx.Completable; import java.util.concurrent.TimeUnit;
import chat.rocket.android.helper.RxHelper;
import chat.rocket.android.log.RCLog;
import hugo.weaving.DebugLog;
import rx.Observable; import rx.Observable;
import rx.Single;
import rx.subjects.PublishSubject; import rx.subjects.PublishSubject;
/** /**
* Connectivity management implementation. * Connectivity management implementation.
*/ */
/*package*/ class ConnectivityManagerImpl implements ConnectivityManagerApi, ConnectivityManagerInternal { /*package*/ class ConnectivityManagerImpl implements ConnectivityManagerApi, ConnectivityManagerInternal {
private final HashMap<String, Integer> serverConnectivityList = new HashMap<>(); private final HashMap<String, Integer> serverConnectivityList = new HashMap<>();
private final PublishSubject<ServerConnectivity> connectivitySubject = PublishSubject.create(); private final PublishSubject<ServerConnectivity> connectivitySubject = PublishSubject.create();
private Context appContext; private Context appContext;
...@@ -60,29 +63,35 @@ import rx.subjects.PublishSubject; ...@@ -60,29 +63,35 @@ import rx.subjects.PublishSubject;
@Override @Override
public void ensureConnections() { public void ensureConnections() {
for (String hostname : serverConnectivityList.keySet()) { for (String hostname : serverConnectivityList.keySet()) {
connectToServer(hostname); //force connect. connectToServer(hostname) //force connect.
//.doOnError(RCLog::e)
.retryWhen(RxHelper.exponentialBackoff(3, 500, TimeUnit.MILLISECONDS))
.subscribe(_val -> { }, RCLog::e);
} }
} }
@Override @Override
public void addOrUpdateServer(String hostname, @Nullable String name) { public void addOrUpdateServer(String hostname, @Nullable String name, boolean insecure) {
ServerInfoImpl.addOrUpdate(hostname, name); ServerInfoImpl.addOrUpdate(hostname, name);
ServerInfoImpl.setInsecure(hostname, insecure);
if (!serverConnectivityList.containsKey(hostname)) { if (!serverConnectivityList.containsKey(hostname)) {
serverConnectivityList.put(hostname, ServerConnectivity.STATE_DISCONNECTED); serverConnectivityList.put(hostname, ServerConnectivity.STATE_DISCONNECTED);
} }
connectToServerIfNeeded(hostname); connectToServerIfNeeded(hostname)
.subscribe(_val -> { }, RCLog::e);
} }
@Override @Override
public void removeServer(String hostname) { public void removeServer(String hostname) {
ServerInfoImpl.remove(hostname); ServerInfoImpl.remove(hostname);
if (serverConnectivityList.containsKey(hostname)) { if (serverConnectivityList.containsKey(hostname)) {
disconnectFromServerIfNeeded(hostname); disconnectFromServerIfNeeded(hostname)
.subscribe(_val -> { }, RCLog::e);
} }
} }
@Override @Override
public Completable connect(String hostname) { public Single<Boolean> connect(String hostname) {
return connectToServerIfNeeded(hostname); return connectToServerIfNeeded(hostname);
} }
...@@ -104,6 +113,7 @@ import rx.subjects.PublishSubject; ...@@ -104,6 +113,7 @@ import rx.subjects.PublishSubject;
return list; return list;
} }
@DebugLog
@Override @Override
public void notifyConnectionEstablished(String hostname, String session) { public void notifyConnectionEstablished(String hostname, String session) {
ServerInfoImpl.updateSession(hostname, session); ServerInfoImpl.updateSession(hostname, session);
...@@ -112,6 +122,7 @@ import rx.subjects.PublishSubject; ...@@ -112,6 +122,7 @@ import rx.subjects.PublishSubject;
new ServerConnectivity(hostname, ServerConnectivity.STATE_CONNECTED)); new ServerConnectivity(hostname, ServerConnectivity.STATE_CONNECTED));
} }
@DebugLog
@Override @Override
public void notifyConnectionLost(String hostname, int reason) { public void notifyConnectionLost(String hostname, int reason) {
serverConnectivityList.put(hostname, ServerConnectivity.STATE_DISCONNECTED); serverConnectivityList.put(hostname, ServerConnectivity.STATE_DISCONNECTED);
...@@ -124,80 +135,96 @@ import rx.subjects.PublishSubject; ...@@ -124,80 +135,96 @@ import rx.subjects.PublishSubject;
return Observable.concat(Observable.from(getCurrentConnectivityList()), connectivitySubject); return Observable.concat(Observable.from(getCurrentConnectivityList()), connectivitySubject);
} }
private Completable connectToServerIfNeeded(String hostname) { private Single<Boolean> connectToServerIfNeeded(String hostname) {
final int connectivity = serverConnectivityList.get(hostname); return RxHelper.lazy(() -> {
if (connectivity == ServerConnectivity.STATE_CONNECTED) { final int connectivity = serverConnectivityList.get(hostname);
return Completable.complete(); if (connectivity == ServerConnectivity.STATE_CONNECTED) {
} return Single.just(true);
}
if (connectivity == ServerConnectivity.STATE_DISCONNECTING) { if (connectivity == ServerConnectivity.STATE_DISCONNECTING) {
return waitForDisconnected(hostname).andThen(connectToServerIfNeeded(hostname)); return waitForDisconnected(hostname)
} .flatMap(_val -> connectToServerIfNeeded(hostname));
}
if (connectivity == ServerConnectivity.STATE_CONNECTING) { if (connectivity == ServerConnectivity.STATE_CONNECTING) {
return waitForConnected(hostname); return waitForConnected(hostname);
} }
return connectToServer(hostname).retry(2); return connectToServer(hostname)
//.doOnError(RCLog::e)
.retryWhen(RxHelper.exponentialBackoff(3, 500, TimeUnit.MILLISECONDS));
});
} }
private Completable disconnectFromServerIfNeeded(String hostname) { private Single<Boolean> disconnectFromServerIfNeeded(String hostname) {
final int connectivity = serverConnectivityList.get(hostname); return RxHelper.lazy(() -> {
if (connectivity == ServerConnectivity.STATE_DISCONNECTED) { final int connectivity = serverConnectivityList.get(hostname);
return Completable.complete(); if (connectivity == ServerConnectivity.STATE_DISCONNECTED) {
} return Single.just(true);
}
if (connectivity == ServerConnectivity.STATE_CONNECTING) { if (connectivity == ServerConnectivity.STATE_CONNECTING) {
return waitForConnected(hostname).andThen(disconnectFromServerIfNeeded(hostname)); return waitForConnected(hostname)
} .flatMap(_val -> disconnectFromServerIfNeeded(hostname));
}
if (connectivity == ServerConnectivity.STATE_DISCONNECTING) { if (connectivity == ServerConnectivity.STATE_DISCONNECTING) {
return waitForDisconnected(hostname); return waitForDisconnected(hostname);
} }
return disconnectFromServer(hostname).retry(2); return disconnectFromServer(hostname)
//.doOnError(RCLog::e)
.retryWhen(RxHelper.exponentialBackoff(3, 500, TimeUnit.MILLISECONDS));
});
} }
private Completable waitForConnected(String hostname) { private Single<Boolean> waitForConnected(String hostname) {
return connectivitySubject return connectivitySubject
.filter(serverConnectivity -> (hostname.equals(serverConnectivity.hostname) .filter(serverConnectivity -> (hostname.equals(serverConnectivity.hostname)
&& serverConnectivity.state == ServerConnectivity.STATE_CONNECTED)) && serverConnectivity.state == ServerConnectivity.STATE_CONNECTED))
.first() .first()
.toCompletable(); .map(serverConnectivity -> true)
.toSingle();
} }
private Completable waitForDisconnected(String hostname) { private Single<Boolean> waitForDisconnected(String hostname) {
return connectivitySubject return connectivitySubject
.filter(serverConnectivity -> (hostname.equals(serverConnectivity.hostname) .filter(serverConnectivity -> (hostname.equals(serverConnectivity.hostname)
&& serverConnectivity.state == ServerConnectivity.STATE_DISCONNECTED)) && serverConnectivity.state == ServerConnectivity.STATE_DISCONNECTED))
.first() .first()
.toCompletable(); .map(serverConnectivity -> true)
} .toSingle();
}
private Completable connectToServer(String hostname) {
if (!serverConnectivityList.containsKey(hostname)) { private Single<Boolean> connectToServer(String hostname) {
throw new IllegalArgumentException("hostname not found"); return RxHelper.lazy(() -> {
} if (!serverConnectivityList.containsKey(hostname)) {
serverConnectivityList.put(hostname, ServerConnectivity.STATE_CONNECTING); return Single.error(new IllegalArgumentException("hostname not found"));
}
if (serviceInterface != null) { serverConnectivityList.put(hostname, ServerConnectivity.STATE_CONNECTING);
return serviceInterface.ensureConnectionToServer(hostname);
} else { if (serviceInterface != null) {
return Completable.error(new IllegalStateException("not prepared")); return serviceInterface.ensureConnectionToServer(hostname);
} } else {
} return Single.error(new IllegalStateException("not prepared"));
}
private Completable disconnectFromServer(String hostname) { });
if (!serverConnectivityList.containsKey(hostname)) { }
throw new IllegalArgumentException("hostname not found");
} private Single<Boolean> disconnectFromServer(String hostname) {
serverConnectivityList.put(hostname, ServerConnectivity.STATE_DISCONNECTING); return RxHelper.lazy(() -> {
if (!serverConnectivityList.containsKey(hostname)) {
if (serviceInterface != null) { return Single.error(new IllegalArgumentException("hostname not found"));
return serviceInterface.disconnectFromServer(hostname); }
} else { serverConnectivityList.put(hostname, ServerConnectivity.STATE_DISCONNECTING);
return Completable.error(new IllegalStateException("not prepared"));
} if (serviceInterface != null) {
return serviceInterface.disconnectFromServer(hostname);
} else {
return Single.error(new IllegalStateException("not prepared"));
}
});
} }
} }
package chat.rocket.android.service; package chat.rocket.android.service;
import rx.Completable; import rx.Single;
public interface ConnectivityServiceInterface { public interface ConnectivityServiceInterface {
Completable ensureConnectionToServer(String hostname); Single<Boolean> ensureConnectionToServer(String hostname);
Completable disconnectFromServer(String hostname); Single<Boolean> disconnectFromServer(String hostname);
} }
...@@ -10,7 +10,9 @@ import android.support.annotation.Nullable; ...@@ -10,7 +10,9 @@ import android.support.annotation.Nullable;
import java.util.HashMap; import java.util.HashMap;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import rx.Completable; import chat.rocket.android.helper.RxHelper;
import hugo.weaving.DebugLog;
import rx.Observable;
import rx.Single; import rx.Single;
/** /**
...@@ -32,7 +34,7 @@ public class RocketChatService extends Service implements ConnectivityServiceInt ...@@ -32,7 +34,7 @@ public class RocketChatService extends Service implements ConnectivityServiceInt
/** /**
* ensure RocketChatService alive. * ensure RocketChatService alive.
*/ */
public static void keepAlive(Context context) { /*package*/ static void keepAlive(Context context) {
context.startService(new Intent(context, RocketChatService.class)); context.startService(new Intent(context, RocketChatService.class));
} }
...@@ -61,43 +63,50 @@ public class RocketChatService extends Service implements ConnectivityServiceInt ...@@ -61,43 +63,50 @@ public class RocketChatService extends Service implements ConnectivityServiceInt
} }
@Override @Override
public Completable ensureConnectionToServer(String hostname) { //called via binder. public Single<Boolean> ensureConnectionToServer(String hostname) { //called via binder.
return getOrCreateWebSocketThread(hostname) return getOrCreateWebSocketThread(hostname)
.doOnError(err -> { .doOnError(err -> {
webSocketThreads.remove(hostname); webSocketThreads.remove(hostname);
connectivityManager.notifyConnectionLost(hostname, ConnectivityManagerInternal.REASON_NETWORK_ERROR); connectivityManager.notifyConnectionLost(hostname, ConnectivityManagerInternal.REASON_NETWORK_ERROR);
}) })
.flatMapCompletable(webSocketThreads -> webSocketThreads.keepAlive()); .flatMap(webSocketThreads -> webSocketThreads.keepAlive());
} }
@Override @Override
public Completable disconnectFromServer(String hostname) { //called via binder. public Single<Boolean> disconnectFromServer(String hostname) { //called via binder.
if (!webSocketThreads.containsKey(hostname)) { return RxHelper.lazy(() -> {
return Completable.complete(); if (!webSocketThreads.containsKey(hostname)) {
} return Single.just(true);
}
RocketChatWebSocketThread thread = webSocketThreads.get(hostname);
if (thread != null) {
return thread.terminate();
} else {
return Completable.timer(1, TimeUnit.SECONDS).andThen(disconnectFromServer(hostname));
}
}
private Single<RocketChatWebSocketThread> getOrCreateWebSocketThread(String hostname) {
if (webSocketThreads.containsKey(hostname)) {
RocketChatWebSocketThread thread = webSocketThreads.get(hostname); RocketChatWebSocketThread thread = webSocketThreads.get(hostname);
if (thread != null) { if (thread != null) {
return Single.just(thread); return thread.terminate();
} else { } else {
return Completable.timer(1, TimeUnit.SECONDS).andThen(getOrCreateWebSocketThread(hostname)); return Observable.timer(1, TimeUnit.SECONDS).toSingle()
.flatMap(_val -> disconnectFromServer(hostname));
} }
} });
webSocketThreads.put(hostname, null); }
return RocketChatWebSocketThread.getStarted(getApplicationContext(), hostname)
.doOnSuccess(thread -> { @DebugLog
webSocketThreads.put(hostname, thread); private Single<RocketChatWebSocketThread> getOrCreateWebSocketThread(String hostname) {
}); return RxHelper.lazy(() -> {
if (webSocketThreads.containsKey(hostname)) {
RocketChatWebSocketThread thread = webSocketThreads.get(hostname);
if (thread != null) {
return Single.just(thread);
} else {
return Observable.timer(1, TimeUnit.SECONDS).toSingle()
.flatMap(_val -> getOrCreateWebSocketThread(hostname));
}
}
webSocketThreads.put(hostname, null);
return RocketChatWebSocketThread.getStarted(getApplicationContext(), hostname)
.doOnSuccess(thread -> {
webSocketThreads.put(hostname, thread);
});
});
} }
@Nullable @Nullable
......
...@@ -32,8 +32,9 @@ import chat.rocket.android.service.observer.PushSettingsObserver; ...@@ -32,8 +32,9 @@ import chat.rocket.android.service.observer.PushSettingsObserver;
import chat.rocket.android.service.observer.SessionObserver; import chat.rocket.android.service.observer.SessionObserver;
import chat.rocket.android.service.observer.TokenLoginObserver; import chat.rocket.android.service.observer.TokenLoginObserver;
import hugo.weaving.DebugLog; import hugo.weaving.DebugLog;
import rx.Completable;
import rx.Single; import rx.Single;
import rx.SingleEmitter;
import rx.functions.Action1;
/** /**
* Thread for handling WebSocket connection. * Thread for handling WebSocket connection.
...@@ -89,7 +90,7 @@ public class RocketChatWebSocketThread extends HandlerThread { ...@@ -89,7 +90,7 @@ public class RocketChatWebSocketThread extends HandlerThread {
} }
}.start(); }.start();
}).flatMap(webSocket -> }).flatMap(webSocket ->
webSocket.connect().andThen(Single.just(webSocket))); webSocket.connect().map(_val -> webSocket));
} }
@Override @Override
...@@ -115,23 +116,23 @@ public class RocketChatWebSocketThread extends HandlerThread { ...@@ -115,23 +116,23 @@ public class RocketChatWebSocketThread extends HandlerThread {
* terminate WebSocket thread. * terminate WebSocket thread.
*/ */
@DebugLog @DebugLog
public Completable terminate() { public Single<Boolean> terminate() {
if (isAlive()) { if (isAlive()) {
return Completable.fromEmitter(completableEmitter -> { return Single.fromEmitter(emitter -> {
new Handler(getLooper()).post(() -> { new Handler(getLooper()).post(() -> {
RCLog.d("thread %s: terminated()", Thread.currentThread().getId()); RCLog.d("thread %s: terminated()", Thread.currentThread().getId());
unregisterListeners(); unregisterListeners();
connectivityManager.notifyConnectionLost(hostname, connectivityManager.notifyConnectionLost(hostname,
ConnectivityManagerInternal.REASON_CLOSED_BY_USER); ConnectivityManagerInternal.REASON_CLOSED_BY_USER);
RocketChatWebSocketThread.super.quit(); RocketChatWebSocketThread.super.quit();
completableEmitter.onCompleted(); emitter.onSuccess(true);
}); });
}); });
} else { } else {
connectivityManager.notifyConnectionLost(hostname, connectivityManager.notifyConnectionLost(hostname,
ConnectivityManagerInternal.REASON_NETWORK_ERROR); ConnectivityManagerInternal.REASON_NETWORK_ERROR);
super.quit(); super.quit();
return Completable.complete(); return Single.just(true);
} }
} }
...@@ -147,9 +148,9 @@ public class RocketChatWebSocketThread extends HandlerThread { ...@@ -147,9 +148,9 @@ public class RocketChatWebSocketThread extends HandlerThread {
* synchronize the state of the thread with ServerConfig. * synchronize the state of the thread with ServerConfig.
*/ */
@DebugLog @DebugLog
public Completable keepAlive() { public Single<Boolean> keepAlive() {
return checkIfConnectionAlive() return checkIfConnectionAlive()
.flatMapCompletable(alive -> alive ? Completable.complete() : connect()); .flatMap(alive -> alive ? Single.just(true) : connect());
} }
private Single<Boolean> checkIfConnectionAlive() { private Single<Boolean> checkIfConnectionAlive() {
...@@ -157,27 +158,37 @@ public class RocketChatWebSocketThread extends HandlerThread { ...@@ -157,27 +158,37 @@ public class RocketChatWebSocketThread extends HandlerThread {
return Single.just(false); return Single.just(false);
} }
return Single.fromEmitter(booleanSingleEmitter -> { return Single.fromEmitter(emitter -> {
ddpClient.ping().continueWith(task -> { new Thread() {
booleanSingleEmitter.onSuccess(!task.isFaulted()); @Override
return null; public void run() {
}); ddpClient.ping().continueWith(task -> {
if (task.isFaulted()) {
RCLog.e(task.getError());
emitter.onSuccess(false);
ddpClient.close();
} else {
emitter.onSuccess(true);
}
return null;
});
}
}.start();
}); });
} }
private Completable prepareDDPClient() { private Single<Boolean> prepareDDPClient() {
return checkIfConnectionAlive() return checkIfConnectionAlive()
.doOnSuccess(alive -> { .doOnSuccess(alive -> {
if (!alive) { if (!alive) {
ddpClient = DDPClientWrapper.create(hostname); ddpClient = DDPClientWrapper.create(hostname);
} }
}) });
.toCompletable();
} }
private Completable connectDDPClient() { private Single<Boolean> connectDDPClient() {
return prepareDDPClient() return prepareDDPClient()
.andThen(Completable.fromEmitter(completableEmitter -> { .flatMap(_val -> Single.fromEmitter(emitter -> {
ServerInfo info = connectivityManager.getServerInfoForHost(hostname); ServerInfo info = connectivityManager.getServerInfoForHost(hostname);
ddpClient.connect(info.session, !info.insecure) ddpClient.connect(info.session, !info.insecure)
.onSuccessTask(task -> { .onSuccessTask(task -> {
...@@ -203,9 +214,9 @@ public class RocketChatWebSocketThread extends HandlerThread { ...@@ -203,9 +214,9 @@ public class RocketChatWebSocketThread extends HandlerThread {
}) })
.continueWith(task -> { .continueWith(task -> {
if (task.isFaulted()) { if (task.isFaulted()) {
completableEmitter.onError(task.getError()); emitter.onError(task.getError());
} else { } else {
completableEmitter.onCompleted(); emitter.onSuccess(true);
} }
return null; return null;
}); });
...@@ -213,12 +224,15 @@ public class RocketChatWebSocketThread extends HandlerThread { ...@@ -213,12 +224,15 @@ public class RocketChatWebSocketThread extends HandlerThread {
} }
@DebugLog @DebugLog
private Completable connect() { private Single<Boolean> connect() {
return connectDDPClient() return connectDDPClient()
.andThen(Completable.fromEmitter(completableEmitter -> { .flatMap(_val -> Single.fromEmitter(new Action1<SingleEmitter<Boolean>>() {
fetchPublicSettings(); @Override
registerListeners(); public void call(SingleEmitter<Boolean> emitter) {
completableEmitter.onCompleted(); fetchPublicSettings();
registerListeners();
emitter.onSuccess(true);
}
})); }));
} }
......
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
<string name="fragment_login_password">Password</string> <string name="fragment_login_password">Password</string>
<string name="fragment_retry_login_retry_title">RETRY</string> <string name="fragment_retry_login_retry_title">RETRY</string>
<string name="fragment_retry_login_error_title">Connection Error</string> <string name="fragment_retry_login_error_title">Connection Error</string>
<string name="add_server_activity_waiting_server">Connecting to server…</string>
<string name="server_config_activity_authenticating">Authenticating…</string> <string name="server_config_activity_authenticating">Authenticating…</string>
<string name="home_fragment_title">Rocket.Chat - Home</string> <string name="home_fragment_title">Rocket.Chat - Home</string>
<string name="fragment_sidebar_main_unread_rooms_title">UNREAD ROOMS</string> <string name="fragment_sidebar_main_unread_rooms_title">UNREAD ROOMS</string>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment