Commit 492e3d0e authored by Leonardo Aramaki's avatar Leonardo Aramaki

Implement opened rooms caching

parent eefec932
...@@ -28,271 +28,308 @@ import okhttp3.HttpUrl; ...@@ -28,271 +28,308 @@ import okhttp3.HttpUrl;
* sharedpreference-based cache. * sharedpreference-based cache.
*/ */
public class RocketChatCache { public class RocketChatCache {
private static final String KEY_SELECTED_SERVER_HOSTNAME = "KEY_SELECTED_SERVER_HOSTNAME"; private static final String KEY_SELECTED_SERVER_HOSTNAME = "KEY_SELECTED_SERVER_HOSTNAME";
private static final String KEY_SELECTED_SITE_URL = "KEY_SELECTED_SITE_URL"; private static final String KEY_SELECTED_SITE_URL = "KEY_SELECTED_SITE_URL";
private static final String KEY_SELECTED_SITE_NAME = "KEY_SELECTED_SITE_NAME"; private static final String KEY_SELECTED_SITE_NAME = "KEY_SELECTED_SITE_NAME";
private static final String KEY_SELECTED_ROOM_ID = "KEY_SELECTED_ROOM_ID"; private static final String KEY_SELECTED_ROOM_ID = "KEY_SELECTED_ROOM_ID";
private static final String KEY_PUSH_ID = "KEY_PUSH_ID"; private static final String KEY_PUSH_ID = "KEY_PUSH_ID";
private static final String KEY_HOSTNAME_LIST = "KEY_HOSTNAME_LIST"; private static final String KEY_HOSTNAME_LIST = "KEY_HOSTNAME_LIST";
private static final String KEY_OPENED_ROOMS = "KEY_OPENED_ROOMS";
private Context context;
private Context context;
public RocketChatCache(Context context) {
this.context = context.getApplicationContext(); public RocketChatCache(Context context) {
} this.context = context.getApplicationContext();
public String getSelectedServerHostname() {
return getString(KEY_SELECTED_SERVER_HOSTNAME, null);
}
public void setSelectedServerHostname(String hostname) {
String newHostname = null;
if (hostname != null) {
newHostname = hostname.toLowerCase();
} }
setString(KEY_SELECTED_SERVER_HOSTNAME, newHostname);
} public void addOpenedRoom(@NonNull String roomId, long lastSeen) {
JSONObject openedRooms = getOpenedRooms();
public void addHostSiteName(@NonNull String currentHostname, @NonNull String siteName) { try {
try { JSONObject room = new JSONObject().put("rid", roomId).put("ls", lastSeen);
String hostSiteNamesJson = getHostSiteNamesJson(); openedRooms.put(roomId, room);
JSONObject jsonObject = (hostSiteNamesJson == null) ? } catch (JSONException e) {
new JSONObject() : new JSONObject(hostSiteNamesJson); RCLog.e(e);
jsonObject.put(currentHostname, siteName); }
setString(KEY_SELECTED_SITE_NAME, jsonObject.toString()); setString(KEY_OPENED_ROOMS, openedRooms.toString());
} catch (JSONException e) {
RCLog.e(e);
} }
}
public void removeOpenedRoom(@NonNull String roomId) {
public @NonNull String getHostSiteName(@NonNull String host) { JSONObject openedRooms = getOpenedRooms();
if (host.startsWith("http")) { if (openedRooms.has(roomId)) {
HttpUrl url = HttpUrl.parse(host); openedRooms.remove(roomId);
if (url != null) { }
host = url.host();
}
} }
try {
String hostSiteNamesJson = getHostSiteNamesJson(); public @NonNull
JSONObject jsonObject = (hostSiteNamesJson == null) ? JSONObject getOpenedRooms() {
new JSONObject() : new JSONObject(hostSiteNamesJson); String openedRooms = getString(KEY_OPENED_ROOMS, "");
host = getSiteUrlFor(host); if (openedRooms.isEmpty()) {
return jsonObject.optString(host); return new JSONObject();
} catch (JSONException e) { }
RCLog.e(e); try {
return new JSONObject(openedRooms);
} catch (JSONException e) {
RCLog.e(e);
}
return new JSONObject();
} }
return "";
}
private @Nullable String getHostSiteNamesJson() { public String getSelectedServerHostname() {
return getString(KEY_SELECTED_SITE_NAME, null); return getString(KEY_SELECTED_SERVER_HOSTNAME, null);
} }
public void addHostnameSiteUrl(@Nullable String hostnameAlias, @NonNull String currentHostname) { public void setSelectedServerHostname(String hostname) {
String alias = null; String newHostname = null;
if (hostnameAlias != null) { if (hostname != null) {
alias = hostnameAlias.toLowerCase(); newHostname = hostname.toLowerCase();
}
setString(KEY_SELECTED_SERVER_HOSTNAME, newHostname);
} }
try {
String selectedHostnameAliasJson = getLoginHostnamesJson(); public void addHostSiteName(@NonNull String currentHostname, @NonNull String siteName) {
JSONObject jsonObject = selectedHostnameAliasJson == null ? try {
new JSONObject() : new JSONObject(selectedHostnameAliasJson); String hostSiteNamesJson = getHostSiteNamesJson();
jsonObject.put(alias, currentHostname); JSONObject jsonObject = (hostSiteNamesJson == null) ?
setString(KEY_SELECTED_SITE_URL, jsonObject.toString()); new JSONObject() : new JSONObject(hostSiteNamesJson);
} catch (JSONException e) { jsonObject.put(currentHostname, siteName);
RCLog.e(e); setString(KEY_SELECTED_SITE_NAME, jsonObject.toString());
} catch (JSONException e) {
RCLog.e(e);
}
} }
}
public @Nullable String getSiteUrlFor(String hostname) { public @NonNull
try { String getHostSiteName(@NonNull String host) {
String selectedServerHostname = getSelectedServerHostname(); if (host.startsWith("http")) {
if (getLoginHostnamesJson() == null || getLoginHostnamesJson().isEmpty()) { HttpUrl url = HttpUrl.parse(host);
if (url != null) {
host = url.host();
}
}
try {
String hostSiteNamesJson = getHostSiteNamesJson();
JSONObject jsonObject = (hostSiteNamesJson == null) ?
new JSONObject() : new JSONObject(hostSiteNamesJson);
host = getSiteUrlFor(host);
return jsonObject.optString(host);
} catch (JSONException e) {
RCLog.e(e);
}
return "";
}
private @Nullable
String getHostSiteNamesJson() {
return getString(KEY_SELECTED_SITE_NAME, null);
}
public void addHostnameSiteUrl(@Nullable String hostnameAlias, @NonNull String currentHostname) {
String alias = null;
if (hostnameAlias != null) {
alias = hostnameAlias.toLowerCase();
}
try {
String selectedHostnameAliasJson = getLoginHostnamesJson();
JSONObject jsonObject = selectedHostnameAliasJson == null ?
new JSONObject() : new JSONObject(selectedHostnameAliasJson);
jsonObject.put(alias, currentHostname);
setString(KEY_SELECTED_SITE_URL, jsonObject.toString());
} catch (JSONException e) {
RCLog.e(e);
}
}
public @Nullable
String getSiteUrlFor(String hostname) {
try {
String selectedServerHostname = getSelectedServerHostname();
if (getLoginHostnamesJson() == null || getLoginHostnamesJson().isEmpty()) {
return null;
}
return new JSONObject(getLoginHostnamesJson())
.optString(hostname, selectedServerHostname);
} catch (JSONException e) {
RCLog.e(e);
}
return null; return null;
}
return new JSONObject(getLoginHostnamesJson())
.optString(hostname, selectedServerHostname);
} catch (JSONException e) {
RCLog.e(e);
} }
return null;
} private @Nullable
String getLoginHostnamesJson() {
private @Nullable String getLoginHostnamesJson() { return getString(KEY_SELECTED_SITE_URL, null);
return getString(KEY_SELECTED_SITE_URL, null);
}
public void addHostname(@NonNull String hostname, @Nullable String hostnameAvatarUri, String siteName) {
String hostnameList = getString(KEY_HOSTNAME_LIST, null);
try {
JSONObject json;
if (hostnameList == null) {
json = new JSONObject();
} else {
json = new JSONObject(hostnameList);
}
JSONObject serverInfoJson = new JSONObject();
serverInfoJson.put("avatar", hostnameAvatarUri);
serverInfoJson.put("sitename", siteName);
// Replace server avatar uri if exists.
json.put(hostname, hostnameAvatarUri == null ? JSONObject.NULL : serverInfoJson);
setString(KEY_HOSTNAME_LIST, json.toString());
} catch (JSONException e) {
RCLog.e(e);
} }
}
public List<Pair<String, Pair<String, String>>> getServerList() { public void addHostname(@NonNull String hostname, @Nullable String hostnameAvatarUri, String siteName) {
String json = getString(KEY_HOSTNAME_LIST, null); String hostnameList = getString(KEY_HOSTNAME_LIST, null);
if (json == null) { try {
return Collections.emptyList(); JSONObject json;
if (hostnameList == null) {
json = new JSONObject();
} else {
json = new JSONObject(hostnameList);
}
JSONObject serverInfoJson = new JSONObject();
serverInfoJson.put("avatar", hostnameAvatarUri);
serverInfoJson.put("sitename", siteName);
// Replace server avatar uri if exists.
json.put(hostname, hostnameAvatarUri == null ? JSONObject.NULL : serverInfoJson);
setString(KEY_HOSTNAME_LIST, json.toString());
} catch (JSONException e) {
RCLog.e(e);
}
} }
try {
JSONObject jsonObj = new JSONObject(json); public List<Pair<String, Pair<String, String>>> getServerList() {
List<Pair<String, Pair<String, String>>> serverList = new ArrayList<>(); String json = getString(KEY_HOSTNAME_LIST, null);
for (Iterator<String> iter = jsonObj.keys(); iter.hasNext();) { if (json == null) {
String hostname = iter.next(); return Collections.emptyList();
JSONObject serverInfoJson = jsonObj.getJSONObject(hostname); }
serverList.add(new Pair<>(hostname, new Pair<>( try {
"http://" + hostname + "/" + serverInfoJson.getString("avatar"), JSONObject jsonObj = new JSONObject(json);
serverInfoJson.getString("sitename")))); List<Pair<String, Pair<String, String>>> serverList = new ArrayList<>();
} for (Iterator<String> iter = jsonObj.keys(); iter.hasNext(); ) {
return serverList; String hostname = iter.next();
} catch (JSONException e) { JSONObject serverInfoJson = jsonObj.getJSONObject(hostname);
RCLog.e(e); serverList.add(new Pair<>(hostname, new Pair<>(
"http://" + hostname + "/" + serverInfoJson.getString("avatar"),
serverInfoJson.getString("sitename"))));
}
return serverList;
} catch (JSONException e) {
RCLog.e(e);
}
return Collections.emptyList();
} }
return Collections.emptyList();
}
public void removeHostname(String hostname) { public void removeHostname(String hostname) {
String json = getString(KEY_HOSTNAME_LIST, null); String json = getString(KEY_HOSTNAME_LIST, null);
if (TextUtils.isEmpty(json)) { if (TextUtils.isEmpty(json)) {
return; return;
}
try {
JSONObject jsonObj = new JSONObject(json);
jsonObj.remove(hostname);
String result = jsonObj.length() == 0 ? null : jsonObj.toString();
setString(KEY_HOSTNAME_LIST, result);
} catch (JSONException e) {
RCLog.e(e);
}
}
@Nullable
public String getFirstLoggedHostnameIfAny() {
String json = getString(KEY_HOSTNAME_LIST, null);
if (json != null) {
try {
JSONObject jsonObj = new JSONObject(json);
if (jsonObj.length() > 0 && jsonObj.keys().hasNext()) {
// Returns the first hostname on the list.
return jsonObj.keys().next();
}
} catch (JSONException e) {
RCLog.e(e);
}
}
return null;
}
public String getSelectedRoomId() {
try {
JSONObject jsonObject = getSelectedRoomIdJsonObject();
return jsonObject.optString(getSelectedServerHostname(), null);
} catch (JSONException e) {
RCLog.e(e);
Logger.report(e);
}
return null;
}
public void setSelectedRoomId(String roomId) {
try {
JSONObject jsonObject = getSelectedRoomIdJsonObject();
jsonObject.put(getSelectedServerHostname(), roomId);
setString(KEY_SELECTED_ROOM_ID, jsonObject.toString());
} catch (JSONException e) {
RCLog.e(e);
Logger.report(e);
}
} }
try {
JSONObject jsonObj = new JSONObject(json); private JSONObject getSelectedRoomIdJsonObject() throws JSONException {
jsonObj.remove(hostname); String json = getString(KEY_SELECTED_ROOM_ID, null);
String result = jsonObj.length() == 0 ? null : jsonObj.toString(); if (json == null) {
setString(KEY_HOSTNAME_LIST, result); return new JSONObject();
} catch (JSONException e) { }
RCLog.e(e); return new JSONObject(json);
} }
}
public String getOrCreatePushId() {
@Nullable SharedPreferences preferences = getSharedPreferences();
public String getFirstLoggedHostnameIfAny() { if (!preferences.contains(KEY_PUSH_ID)) {
String json = getString(KEY_HOSTNAME_LIST, null); // generates one and save
if (json != null) { String newId = UUID.randomUUID().toString().replace("-", "");
try { preferences.edit()
JSONObject jsonObj = new JSONObject(json); .putString(KEY_PUSH_ID, newId)
if (jsonObj.length() > 0 && jsonObj.keys().hasNext()) { .apply();
// Returns the first hostname on the list. return newId;
return jsonObj.keys().next();
} }
} catch (JSONException e) { return preferences.getString(KEY_PUSH_ID, null);
RCLog.e(e);
}
} }
return null;
} public Flowable<Optional<String>> getSelectedServerHostnamePublisher() {
return getValuePublisher(KEY_SELECTED_SERVER_HOSTNAME);
public String getSelectedRoomId() {
try {
JSONObject jsonObject = getSelectedRoomIdJsonObject();
return jsonObject.optString(getSelectedServerHostname(), null);
} catch (JSONException e) {
RCLog.e(e);
Logger.report(e);
} }
return null;
} public Flowable<Optional<String>> getSelectedRoomIdPublisher() {
return getValuePublisher(KEY_SELECTED_ROOM_ID)
public void setSelectedRoomId(String roomId) { .filter(Optional::isPresent)
try { .map(Optional::get)
JSONObject jsonObject = getSelectedRoomIdJsonObject(); .map(roomValue -> Optional.ofNullable(new JSONObject(roomValue).optString(getSelectedServerHostname(), null)));
jsonObject.put(getSelectedServerHostname(), roomId);
setString(KEY_SELECTED_ROOM_ID, jsonObject.toString());
} catch (JSONException e) {
RCLog.e(e);
Logger.report(e);
} }
}
private JSONObject getSelectedRoomIdJsonObject() throws JSONException { private SharedPreferences getSharedPreferences() {
String json = getString(KEY_SELECTED_ROOM_ID, null); return context.getSharedPreferences("cache", Context.MODE_PRIVATE);
if (json == null) {
return new JSONObject();
} }
return new JSONObject(json);
} private SharedPreferences.Editor getEditor() {
return getSharedPreferences().edit();
public String getOrCreatePushId() {
SharedPreferences preferences = getSharedPreferences();
if (!preferences.contains(KEY_PUSH_ID)) {
// generates one and save
String newId = UUID.randomUUID().toString().replace("-", "");
preferences.edit()
.putString(KEY_PUSH_ID, newId)
.apply();
return newId;
} }
return preferences.getString(KEY_PUSH_ID, null);
} public String getString(String key, String defaultValue) {
return getSharedPreferences().getString(key, defaultValue);
public Flowable<Optional<String>> getSelectedServerHostnamePublisher() { }
return getValuePublisher(KEY_SELECTED_SERVER_HOSTNAME);
} private void setString(String key, String value) {
getEditor().putString(key, value).apply();
public Flowable<Optional<String>> getSelectedRoomIdPublisher() { }
return getValuePublisher(KEY_SELECTED_ROOM_ID)
.filter(Optional::isPresent) private Flowable<Optional<String>> getValuePublisher(final String key) {
.map(Optional::get) return Flowable.create(emitter -> {
.map(roomValue -> Optional.ofNullable(new JSONObject(roomValue).optString(getSelectedServerHostname(), null))); SharedPreferences.OnSharedPreferenceChangeListener
} listener = (sharedPreferences, changedKey) -> {
if (key.equals(changedKey) && !emitter.isCancelled()) {
private SharedPreferences getSharedPreferences() { String value = getString(key, null);
return context.getSharedPreferences("cache", Context.MODE_PRIVATE); emitter.onNext(Optional.ofNullable(value));
} }
};
private SharedPreferences.Editor getEditor() {
return getSharedPreferences().edit(); emitter.setCancellable(() -> getSharedPreferences()
} .unregisterOnSharedPreferenceChangeListener(listener));
public String getString(String key, String defaultValue) { getSharedPreferences().registerOnSharedPreferenceChangeListener(listener);
return getSharedPreferences().getString(key, defaultValue); }, BackpressureStrategy.LATEST);
} }
private void setString(String key, String value) { public void removeSelectedRoomId(String currentHostname) {
getEditor().putString(key, value).apply(); try {
} JSONObject selectedRoomIdJsonObject = getSelectedRoomIdJsonObject();
selectedRoomIdJsonObject.remove(currentHostname);
private Flowable<Optional<String>> getValuePublisher(final String key) { String result = selectedRoomIdJsonObject.length() == 0 ?
return Flowable.create(emitter -> { null : selectedRoomIdJsonObject.toString();
SharedPreferences.OnSharedPreferenceChangeListener setString(KEY_SELECTED_ROOM_ID, result);
listener = (sharedPreferences, changedKey) -> { } catch (JSONException e) {
if (key.equals(changedKey) && !emitter.isCancelled()) { Logger.report(e);
String value = getString(key, null); RCLog.e(e);
emitter.onNext(Optional.ofNullable(value));
} }
};
emitter.setCancellable(() -> getSharedPreferences()
.unregisterOnSharedPreferenceChangeListener(listener));
getSharedPreferences().registerOnSharedPreferenceChangeListener(listener);
}, BackpressureStrategy.LATEST);
}
public void removeSelectedRoomId(String currentHostname) {
try {
JSONObject selectedRoomIdJsonObject = getSelectedRoomIdJsonObject();
selectedRoomIdJsonObject.remove(currentHostname);
String result = selectedRoomIdJsonObject.length() == 0 ?
null : selectedRoomIdJsonObject.toString();
setString(KEY_SELECTED_ROOM_ID, result);
} catch (JSONException e) {
Logger.report(e);
RCLog.e(e);
} }
}
} }
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