Skip to content

Commit

Permalink
Merge pull request #237 from jlewis13/monitors
Browse files Browse the repository at this point in the history
Monitors and Directory Search
  • Loading branch information
jlewis13 authored Dec 12, 2017
2 parents b5d4d80 + 5ce4e71 commit e66df26
Show file tree
Hide file tree
Showing 32 changed files with 497 additions and 379 deletions.
13 changes: 5 additions & 8 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,8 @@ android {
applicationId 'io.forsta.relay'
minSdkVersion 14
targetSdkVersion 22
versionName "0.1.76"
versionCode 176
versionName "0.1.78"
versionCode 178
multiDexEnabled true
buildConfigField "long", "BUILD_TIMESTAMP", getLastCommitTimestamp() + "L"
resValue "string", "forsta_authorities", applicationId + '.provider.ccsm'
Expand All @@ -166,23 +166,20 @@ android {
productFlavors {
dev {
applicationIdSuffix '.dev'
buildConfigField "String", "FORSTA_API_URL", "\"https://ccsm-dev-api.forsta.io\""
buildConfigField "String", "FORSTA_SYNC_NUMBER", "\"1e1116aa-31b3-4fb2-a4db-21e8136d4f3a\""
buildConfigField "String", "FORSTA_API_URL", "\"https://atlas-dev.forsta.io\""
resValue "string", "forsta_authorities", defaultConfig.applicationId + applicationIdSuffix + '.provider.ccsm'
resValue "string", "forsta_account_type", defaultConfig.applicationId + applicationIdSuffix
buildConfigField "String", "FORSTA_PROVISION_SERVICE_TOKEN", dev_service_config
}
stage {
applicationIdSuffix '.stage'
buildConfigField "String", "FORSTA_API_URL", "\"https://ccsm-stage-api.forsta.io\""
buildConfigField "String", "FORSTA_SYNC_NUMBER", "\"88e7165e-d2da-4c3f-a14a-bb802bb0cefb\""
buildConfigField "String", "FORSTA_API_URL", "\"https://atlas-stage.forsta.io\""
resValue "string", "forsta_authorities", defaultConfig.applicationId + applicationIdSuffix + '.provider.ccsm'
resValue "string", "forsta_account_type", defaultConfig.applicationId + applicationIdSuffix
buildConfigField "String", "FORSTA_PROVISION_SERVICE_TOKEN", stage_service_config
}
prod {
buildConfigField "String", "FORSTA_API_URL", "\"https://api.forsta.io\""
buildConfigField "String", "FORSTA_SYNC_NUMBER", "\"cf40fca2-dfa8-4356-8ae7-45f56f7551ca\""
buildConfigField "String", "FORSTA_API_URL", "\"https://atlas.forsta.io\""
buildConfigField "String", "FORSTA_PROVISION_SERVICE_TOKEN", prod_service_config
}
}
Expand Down
24 changes: 10 additions & 14 deletions res/layout/activity_dashboard.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,26 +24,22 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Message Tests: "/>
<Button android:id="@+id/message_tests_button"
<Button
android:id="@+id/socket_tester"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:text="Go"/>
android:text="Open Socket"
android:visibility="visible"/>
</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" android:orientation="horizontal">
<Button
android:id="@+id/socket_tester"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Open Socket"
android:visibility="gone"/>
android:layout_height="wrap_content"
android:orientation="vertical">
<EditText
android:id="@+id/search_directory"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>

<TextView
Expand Down
2 changes: 1 addition & 1 deletion res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,7 @@
<string name="contact_selection_activity__enter_name_or_number_sms">Enter name or number</string>
<string name="contact_selection_activity__enter_custom_expression">Enter a tag or tag expression</string>
<string name="contact_selection_activity__title">Create Conversation</string>
<string name="contact_selection_activity__no_results">No results. Click the search icon to search the entire directory.</string>
<string name="contact_selection_activity__no_results">No results.</string>

<!-- contact_selection_group_activity -->
<string name="contact_selection_group_activity__no_contacts">No contacts.</string>
Expand Down
53 changes: 37 additions & 16 deletions src/io/forsta/ccsm/DashboardActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
import android.content.Intent;
import android.database.Cursor;
import android.os.AsyncTask;
import android.provider.ContactsContract;
import android.support.annotation.Nullable;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AlertDialog;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
Expand All @@ -18,13 +19,13 @@
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.ScrollView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import org.json.JSONException;
import org.json.JSONObject;

import io.forsta.ccsm.api.model.ForstaJWT;
Expand All @@ -40,7 +41,6 @@
import io.forsta.securesms.PassphraseRequiredActionBarActivity;
import io.forsta.securesms.R;
import io.forsta.securesms.attachments.DatabaseAttachment;
import io.forsta.securesms.contacts.ContactsDatabase;
import io.forsta.securesms.crypto.MasterCipher;
import io.forsta.securesms.crypto.MasterSecret;
import io.forsta.securesms.database.AttachmentDatabase;
Expand All @@ -54,7 +54,6 @@
import io.forsta.securesms.database.SmsDatabase;
import io.forsta.securesms.database.TextSecureDirectory;
import io.forsta.securesms.database.ThreadDatabase;
import io.forsta.securesms.database.model.DisplayRecord;
import io.forsta.securesms.database.model.MessageRecord;
import io.forsta.securesms.database.model.SmsMessageRecord;
import io.forsta.securesms.database.model.ThreadRecord;
Expand All @@ -65,7 +64,6 @@
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
Expand All @@ -90,7 +88,6 @@ public class DashboardActivity extends PassphraseRequiredActionBarActivity imple
private ProgressBar mProgressBar;
private WebSocketUtils socketUtils;
private Button socketTester;
private Button messageTester;

@Override
protected void onCreate(Bundle savedInstanceState, @Nullable MasterSecret masterSecret) {
Expand Down Expand Up @@ -183,6 +180,7 @@ public void onClick(View view) {
options.add("Get API Users");
options.add("Get API Groups");
options.add("Get Directory");
options.add("Message Tests");

ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item, options);
mSpinner.setAdapter(adapter);
Expand Down Expand Up @@ -237,6 +235,11 @@ public void onItemSelected(AdapterView<?> parent, View view, int position, long
mDebugText.setText("");
GetDirectory directory = new GetDirectory();
directory.execute();
break;
case 11:
mDebugText.setText("");
showScrollView();
new MessageTests().execute();
}
}

Expand All @@ -254,13 +257,31 @@ public void onClick(View v) {
ForstaPreferences.setCCSMDebug(DashboardActivity.this, mToggleSyncMessages.isChecked());
}
});
messageTester = (Button) findViewById(R.id.message_tests_button);
messageTester.setOnClickListener(new View.OnClickListener() {
EditText search = (EditText) findViewById(R.id.search_directory);
search.addTextChangedListener(new TextWatcher() {
@Override
public void onClick(View v) {
mDebugText.setText("");
showScrollView();
new MessageTests().execute();
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

}

@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
if (charSequence.length() > 2) {
new AsyncTask<String, Void, Void>() {
@Override
protected Void doInBackground(String[] objects) {
JSONObject response = CcsmApi.searchUserDirectory(DashboardActivity.this, objects[0]);
List<ForstaUser> users = CcsmApi.parseUsers(DashboardActivity.this, response);
Log.w(TAG, "Getting response");
return null;
}
}.execute(charSequence.toString());
}
}

@Override
public void afterTextChanged(Editable editable) {

}
});
printLoginInformation();
Expand Down Expand Up @@ -319,10 +340,10 @@ private void printLoginInformation() {
sb.append("API Host:");
sb.append(BuildConfig.FORSTA_API_URL);
sb.append("\n");
sb.append("Sync Number:");
sb.append(BuildConfig.FORSTA_SYNC_NUMBER);
Date tokenExpire = jwt.getExpireDate();
sb.append("SIgnal Host:");
sb.append(TextSecurePreferences.getServer(DashboardActivity.this));
sb.append("\n");
Date tokenExpire = jwt.getExpireDate();
sb.append("Token Expires: ");
sb.append(tokenExpire);
sb.append("\n");
Expand Down Expand Up @@ -727,7 +748,7 @@ private class GetTagUsers extends AsyncTask<Void, Void, JSONObject> {

@Override
protected JSONObject doInBackground(Void... voids) {
return CcsmApi.getUsers(DashboardActivity.this);
return CcsmApi.getOrgUsers(DashboardActivity.this);
}

@Override
Expand Down
2 changes: 1 addition & 1 deletion src/io/forsta/ccsm/ForstaLogSubmitFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ private void sendLogEmail() {
stream.close();
Intent emailIntent = new Intent(Intent.ACTION_SEND);
emailIntent.setType("vnd.android.cursor.dir/email");
emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] { "support@forsta.io" });
emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] { "androidsupport@forsta.io" });
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Android App Debug Log");
String out = outFile.getAbsolutePath();
emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(outFile));
Expand Down
120 changes: 83 additions & 37 deletions src/io/forsta/ccsm/api/CcsmApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,44 @@ public static JSONObject forstaSendToken(Context context, String org, String use
}

public static void syncForstaContacts(Context context) {
JSONObject response = getUsers(context);
JSONObject response = getOrgUsers(context);
if (isUnauthorizedResponse(response)) {
return;
}
List<ForstaUser> forstaContacts = parseUsers(context, response);
List<ForstaUser> filteredContacts = new ArrayList<>();


Set<String> systemNumbers = new HashSet<>();
Cursor cursor = null;
try {
cursor = DatabaseFactory.getContactsDatabase(context).querySystemContacts("");
while (cursor != null && cursor.moveToNext()) {
String number = cursor.getString(cursor.getColumnIndex(ContactsDatabase.NUMBER_COLUMN));
systemNumbers.add(number);
}
} finally {
if (cursor != null) {
cursor.close();
}
}

for (int i=0; i< forstaContacts.size(); i++) {
if (systemNumbers.contains(forstaContacts.get(i).getPhone())) {
// forstaContacts.remove(i);
// For debugging, use another filtered list.
// This would restrict full directory sync to only people in local contacts db.
filteredContacts.add(forstaContacts.get(i));
}
}

List<ForstaUser> dbContacts = DbFactory.getContactDb(context).getUsers();
for (ForstaUser user : dbContacts) {
if (!forstaContacts.contains(user)) {
forstaContacts.add(user);
}
}

syncForstaContactsDb(context, forstaContacts, false);
CcsmApi.syncForstaGroups(context);
ForstaPreferences.setForstaContactSync(context, new Date().getTime());
Expand Down Expand Up @@ -148,7 +181,7 @@ public static JSONObject getUserPick(Context context) {
return fetchResource(context, "GET", API_USER_PICK);
}

public static JSONObject getUsers(Context context) {
public static JSONObject getOrgUsers(Context context) {
return fetchResource(context, "GET", API_USER);
}

Expand Down Expand Up @@ -267,7 +300,6 @@ public static ForstaDistribution getMessageDistribution(Context context, String
private static void syncForstaContactsDb(Context context, List<ForstaUser> contacts, boolean removeExisting) {
ContactDb forstaDb = DbFactory.getContactDb(context);
forstaDb.updateUsers(contacts, removeExisting);
forstaDb.close();
}

private static void syncForstaGroups(Context context) {
Expand Down Expand Up @@ -298,6 +330,54 @@ private static boolean isUnauthorizedResponse(JSONObject response) {
return false;
}

public static boolean tokenNeedsRefresh(Context context) {
Date expireDate = ForstaPreferences.getTokenExpireDate(context);
if (expireDate == null) {
return false;
}
Date current = new Date();
long expiresIn = (expireDate.getTime() - current.getTime()) / (1000 * 60 * 60 * 24);
long expireDelta = EXPIRE_REFRESH_DELTA;
boolean expired = expiresIn < expireDelta;

Log.d(TAG, "Token expires in: " + expiresIn);
return expired;
}

public static JSONObject forstaRefreshToken(Context context) {
JSONObject result = new JSONObject();
try {
JSONObject obj = new JSONObject();
obj.put("token", ForstaPreferences.getRegisteredKey(context));
result = fetchResource(context, "POST", API_TOKEN_REFRESH, obj);
if (result.has("token")) {
Log.w(TAG, "Token refresh. New token issued.");
String token = result.getString("token");
ForstaPreferences.setRegisteredForsta(context, token);
} else {
Log.w(TAG, "Token refresh failed.");
ForstaPreferences.setRegisteredForsta(context, "");
}
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "forstaRefreshToken failed");
}
return result;
}

public static JSONObject searchUserDirectory(Context context, String searchText) {
JSONObject response = new JSONObject();
try {
String urlEncoded = TextUtils.isEmpty(searchText) ? "" : URLEncoder.encode(searchText, "UTF-8");
response = fetchResource(context, "GET", API_DIRECTORY_USER + "?q=" + urlEncoded);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return response;
}

// XXX obsolete XXX
private static Set<String> getSystemContacts(Context context) {
Set<String> results = new HashSet<>();
Expand Down Expand Up @@ -349,39 +429,5 @@ private static void createSystemContacts(Context context, List<ForstaUser> conta
}
}

// TODO Is there a reason to ever refresh the token.
public static boolean tokenNeedsRefresh(Context context) {
Date expireDate = ForstaPreferences.getTokenExpireDate(context);
if (expireDate == null) {
return false;
}
Date current = new Date();
long expiresIn = (expireDate.getTime() - current.getTime()) / (1000 * 60 * 60 * 24);
long expireDelta = EXPIRE_REFRESH_DELTA;
boolean expired = expiresIn < expireDelta;

Log.d(TAG, "Token expires in: " + expiresIn);
return expired;
}

public static JSONObject forstaRefreshToken(Context context) {
JSONObject result = new JSONObject();
try {
JSONObject obj = new JSONObject();
obj.put("token", ForstaPreferences.getRegisteredKey(context));
result = fetchResource(context, "POST", API_TOKEN_REFRESH, obj);
if (result.has("token")) {
Log.d(TAG, "Token refresh. New token issued.");
String token = result.getString("token");
ForstaPreferences.setRegisteredForsta(context, token);
} else {
Log.d(TAG, "Token refresh failed.");
ForstaPreferences.setRegisteredForsta(context, "");
}
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "forstaRefreshToken failed");
}
return result;
}
}
Loading

0 comments on commit e66df26

Please sign in to comment.