Update insights copy and queries.

This commit is contained in:
Alex Hart
2019-11-15 16:33:54 -04:00
committed by GitHub
parent 739fe584c6
commit 599bb5ab0f
11 changed files with 62 additions and 86 deletions

View File

@@ -42,6 +42,7 @@ import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencyProvider;
import org.thoughtcrime.securesms.gcm.FcmJobService;
import org.thoughtcrime.securesms.insights.InsightsOptOut;
import org.thoughtcrime.securesms.jobmanager.JobManager;
import org.thoughtcrime.securesms.jobmanager.JobMigrator;
import org.thoughtcrime.securesms.jobmanager.impl.JsonDataSerializer;
@@ -239,6 +240,7 @@ public class ApplicationContext extends MultiDexApplication implements DefaultLi
if (!SQLCipherOpenHelper.databaseFileExists(this)) {
Log.i(TAG, "First ever app launch!");
InsightsOptOut.userRequestedOptOut(this);
TextSecurePreferences.setAppMigrationVersion(this, ApplicationMigrations.CURRENT_VERSION);
TextSecurePreferences.setJobManagerVersion(this, JobManager.CURRENT_VERSION);
}

View File

@@ -7,18 +7,16 @@ import android.text.TextUtils;
import androidx.annotation.NonNull;
import com.annimon.stream.Stream;
import net.sqlcipher.database.SQLiteDatabase;
import org.thoughtcrime.securesms.database.documents.Document;
import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch;
import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatchList;
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
import org.thoughtcrime.securesms.insights.InsightsConstants;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.util.JsonUtils;
import org.thoughtcrime.securesms.util.Util;
import org.whispersystems.libsignal.IdentityKey;
import java.io.IOException;
@@ -49,7 +47,7 @@ public abstract class MessagingDatabase extends Database implements MmsSmsColumn
SQLiteDatabase db = databaseHelper.getReadableDatabase();
String[] projection = new String[]{"COUNT(*)"};
String query = THREAD_ID + " = ? AND " + getOutgoingInsecureMessageClause() + " AND " + getDateSentColumnName() + " > ?";
String[] args = new String[]{String.valueOf(threadId), String.valueOf(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(7))};
String[] args = new String[]{String.valueOf(threadId), String.valueOf(System.currentTimeMillis() - InsightsConstants.PERIOD_IN_MILLIS)};
try (Cursor cursor = db.query(getTableName(), projection, query, args, null, null, null, null)) {
if (cursor != null && cursor.moveToFirst()) {
@@ -60,28 +58,20 @@ public abstract class MessagingDatabase extends Database implements MmsSmsColumn
}
}
final int getInsecureMessageCountForRecipients(List<RecipientId> recipients) {
return getMessageCountForRecipientsAndType(recipients, getOutgoingInsecureMessageClause());
final int getInsecureMessageCountForInsights() {
return getMessageCountForRecipientsAndType(getOutgoingInsecureMessageClause());
}
final int getSecureMessageCountForRecipients(List<RecipientId> recipients) {
return getMessageCountForRecipientsAndType(recipients, getOutgoingSecureMessageClause());
final int getSecureMessageCountForInsights() {
return getMessageCountForRecipientsAndType(getOutgoingSecureMessageClause());
}
private int getMessageCountForRecipientsAndType(List<RecipientId> recipients, String typeClause) {
if (recipients.size() == 0) return 0;
private int getMessageCountForRecipientsAndType(String typeClause) {
SQLiteDatabase db = databaseHelper.getReadableDatabase();
String placeholders = Util.join(Stream.of(recipients).map(r -> "?").toList(), ",");
String[] projection = new String[] {"COUNT(*)"};
String query = RECIPIENT_ID + " IN ( " + placeholders + " ) AND " + typeClause + " AND " + getDateSentColumnName() + " > ?";
String[] args = new String[recipients.size() + 1];
for (int i = 0; i < recipients.size(); i++) {
args[i] = recipients.get(i).serialize();
}
args[args.length - 1] = String.valueOf(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(7));
String query = typeClause + " AND " + getDateSentColumnName() + " > ?";
String[] args = new String[]{String.valueOf(System.currentTimeMillis() - InsightsConstants.PERIOD_IN_MILLIS)};
try (Cursor cursor = db.query(getTableName(), projection, query, args, null, null, null, null)) {
if (cursor != null && cursor.moveToFirst()) {

View File

@@ -18,6 +18,7 @@ package org.thoughtcrime.securesms.database;
import android.content.Context;
import android.database.Cursor;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -31,7 +32,6 @@ import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class MmsSmsDatabase extends Database {
@@ -163,16 +163,16 @@ public class MmsSmsDatabase extends Database {
return count;
}
public int getInsecureMessageCountForRecipients(List<RecipientId> recipients) {
int count = DatabaseFactory.getSmsDatabase(context).getInsecureMessageCountForRecipients(recipients);
count += DatabaseFactory.getMmsDatabase(context).getInsecureMessageCountForRecipients(recipients);
public int getInsecureMessageCountForInsights() {
int count = DatabaseFactory.getSmsDatabase(context).getInsecureMessageCountForInsights();
count += DatabaseFactory.getMmsDatabase(context).getInsecureMessageCountForInsights();
return count;
}
public int getSecureMessageCountForRecipients(List<RecipientId> recipients) {
int count = DatabaseFactory.getSmsDatabase(context).getSecureMessageCountForRecipients(recipients);
count += DatabaseFactory.getMmsDatabase(context).getSecureMessageCountForRecipients(recipients);
public int getSecureMessageCountForInsights() {
int count = DatabaseFactory.getSmsDatabase(context).getSecureMessageCountForInsights();
count += DatabaseFactory.getMmsDatabase(context).getSecureMessageCountForInsights();
return count;
}

View File

@@ -1,6 +1,5 @@
package org.thoughtcrime.securesms.database;
import android.annotation.SuppressLint;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
@@ -37,6 +36,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
public class RecipientDatabase extends Database {
@@ -205,8 +205,9 @@ public class RecipientDatabase extends Database {
TABLE_NAME + "." + GROUP_ID + " IS NULL AND " +
TABLE_NAME + "." + REGISTERED + " = " + RegisteredState.NOT_REGISTERED.id + " AND " +
TABLE_NAME + "." + SEEN_INVITE_REMINDER + " < " + InsightsBannerTier.TIER_TWO.id + " AND " +
ThreadDatabase.TABLE_NAME + "." + ThreadDatabase.HAS_SENT +
" ORDER BY " + ThreadDatabase.TABLE_NAME + "." + ThreadDatabase.DATE + " DESC";
ThreadDatabase.TABLE_NAME + "." + ThreadDatabase.HAS_SENT + " AND " +
ThreadDatabase.TABLE_NAME + "." + ThreadDatabase.DATE + " > ?" +
" ORDER BY " + ThreadDatabase.TABLE_NAME + "." + ThreadDatabase.DATE + " DESC LIMIT 50";
public RecipientDatabase(Context context, SQLCipherOpenHelper databaseHelper) {
super(context, databaseHelper);
@@ -618,33 +619,9 @@ public class RecipientDatabase extends Database {
public @NonNull List<RecipientId> getUninvitedRecipientsForInsights() {
SQLiteDatabase db = databaseHelper.getReadableDatabase();
List<RecipientId> results = new LinkedList<>();
final String[] args = new String[]{String.valueOf(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(31))};
try (Cursor cursor = db.rawQuery(INSIGHTS_INVITEE_LIST, null)) {
while (cursor != null && cursor.moveToNext()) {
results.add(RecipientId.from(cursor.getLong(cursor.getColumnIndexOrThrow(ID))));
}
}
return results;
}
public @NonNull List<RecipientId> getNotRegisteredForInsights() {
return getRecipientsForInsights(REGISTERED + " = ?", new String[]{String.valueOf(RegisteredState.NOT_REGISTERED.id)});
}
public @NonNull List<RecipientId> getRegisteredForInsights() {
final String selfId = Recipient.self().getId().serialize();
final String query = REGISTERED + " = ? AND " + ID + " != ?";
final String[] args = new String[]{String.valueOf(RegisteredState.REGISTERED.id), selfId};
return getRecipientsForInsights(query, args);
}
private @NonNull List<RecipientId> getRecipientsForInsights(@NonNull String query, @NonNull String[] args) {
SQLiteDatabase db = databaseHelper.getReadableDatabase();
List<RecipientId> results = new LinkedList<>();
try (Cursor cursor = db.query(TABLE_NAME, ID_PROJECTION, query + " AND " + GROUP_ID + " IS NULL", args, null, null, null)) {
try (Cursor cursor = db.rawQuery(INSIGHTS_INVITEE_LIST, args)) {
while (cursor != null && cursor.moveToNext()) {
results.add(RecipientId.from(cursor.getLong(cursor.getColumnIndexOrThrow(ID))));
}

View File

@@ -0,0 +1,13 @@
package org.thoughtcrime.securesms.insights;
import java.util.concurrent.TimeUnit;
public final class InsightsConstants {
public static final long PERIOD_IN_DAYS = 7L;
public static final long PERIOD_IN_MILLIS = TimeUnit.DAYS.toMillis(PERIOD_IN_DAYS);
private InsightsConstants() {
}
}

View File

@@ -182,16 +182,18 @@ public final class InsightsDashboardDialogFragment extends DialogFragment {
progressContainer.setVisibility(View.VISIBLE);
insecureRecipients.setVisibility(View.VISIBLE);
encryptedMessages.setText(R.string.InsightsDashboardFragment__encrypted_messages);
tagline.setText(getString(R.string.InsightsDashboardFragment__tagline, 100 - insecurePercent));
tagline.setText(getString(R.string.InsightsDashboardFragment__signal_protocol_automatically_protected, 100 - insecurePercent, InsightsConstants.PERIOD_IN_DAYS));
if (insecurePercent == 0) {
lottieAnimationView.setVisibility(View.VISIBLE);
title.setText(R.string.InsightsDashboardFragment__100_title);
description.setText(R.string.InsightsDashboardFragment__100_description);
title.setVisibility(View.GONE);
description.setVisibility(View.GONE);
} else {
lottieAnimationView.setVisibility(View.GONE);
title.setText(R.string.InsightsDashboardFragment__boost_your_signal);
description.setText(R.string.InsightsDashboardFragment__invite_your_contacts);
title.setVisibility(View.VISIBLE);
description.setVisibility(View.VISIBLE);
}
}
@@ -199,8 +201,8 @@ public final class InsightsDashboardDialogFragment extends DialogFragment {
startAConversation.setVisibility(View.VISIBLE);
progressContainer.setVisibility(View.INVISIBLE);
insecureRecipients.setVisibility(View.GONE);
encryptedMessages.setText(R.string.InsightsDashboardFragment__no_signal_yet);
tagline.setText(R.string.InsightsDashboardFragment__youre_just_getting_started);
encryptedMessages.setText(R.string.InsightsDashboardFragment__not_enough_data);
tagline.setText(getString(R.string.InsightsDashboardFragment__your_insights_percentage_is_calculated_based_on, InsightsConstants.PERIOD_IN_DAYS));
}
private void animateNotEnoughData() {

View File

@@ -6,14 +6,17 @@ import androidx.annotation.NonNull;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
class InsightsOptOut {
public final class InsightsOptOut {
private static final String INSIGHTS_OPT_OUT_PREFERENCE = "insights.opt.out";
private InsightsOptOut() {
}
static boolean userHasOptedOut(@NonNull Context context) {
return TextSecurePreferences.getBooleanPreference(context, INSIGHTS_OPT_OUT_PREFERENCE, false);
}
static void userRequestedOptOut(@NonNull Context context) {
public static void userRequestedOptOut(@NonNull Context context) {
TextSecurePreferences.setBooleanPreference(context, INSIGHTS_OPT_OUT_PREFERENCE, true);
}
}

View File

@@ -16,11 +16,11 @@ import org.thoughtcrime.securesms.contacts.avatars.ProfileContactPhoto;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.MmsSmsDatabase;
import org.thoughtcrime.securesms.database.RecipientDatabase;
import org.thoughtcrime.securesms.database.ThreadDatabase;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.sms.MessageSender;
import org.thoughtcrime.securesms.sms.OutgoingTextMessage;
import org.thoughtcrime.securesms.util.Stopwatch;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
@@ -39,12 +39,9 @@ public class InsightsRepository implements InsightsDashboardViewModel.Repository
@Override
public void getInsightsData(@NonNull Consumer<InsightsData> insightsDataConsumer) {
SimpleTask.run(() -> {
RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context);
List<RecipientId> unregisteredRecipients = recipientDatabase.getNotRegisteredForInsights();
List<RecipientId> registeredRecipients = recipientDatabase.getRegisteredForInsights();
MmsSmsDatabase mmsSmsDatabase = DatabaseFactory.getMmsSmsDatabase(context);
int insecure = mmsSmsDatabase.getInsecureMessageCountForRecipients(unregisteredRecipients);
int secure = mmsSmsDatabase.getSecureMessageCountForRecipients(registeredRecipients);
MmsSmsDatabase mmsSmsDatabase = DatabaseFactory.getMmsSmsDatabase(context);
int insecure = mmsSmsDatabase.getInsecureMessageCountForInsights();
int secure = mmsSmsDatabase.getSecureMessageCountForInsights();
if (insecure + secure == 0) {
return new InsightsData(false, 0);

View File

@@ -6,9 +6,6 @@ import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.MmsSmsDatabase;
import org.thoughtcrime.securesms.database.RecipientDatabase;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import java.util.List;
public final class InviteReminderRepository implements InviteReminderModel.Repository {
@@ -32,12 +29,9 @@ public final class InviteReminderRepository implements InviteReminderModel.Repos
@Override
public int getPercentOfInsecureMessages(int insecureCount) {
RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context);
List<RecipientId> registeredRecipients = recipientDatabase.getRegisteredForInsights();
List<RecipientId> unregisteredRecipients = recipientDatabase.getNotRegisteredForInsights();
MmsSmsDatabase mmsSmsDatabase = DatabaseFactory.getMmsSmsDatabase(context);
int insecure = mmsSmsDatabase.getInsecureMessageCountForRecipients(unregisteredRecipients);
int secure = mmsSmsDatabase.getSecureMessageCountForRecipients(registeredRecipients);
MmsSmsDatabase mmsSmsDatabase = DatabaseFactory.getMmsSmsDatabase(context);
int insecure = mmsSmsDatabase.getInsecureMessageCountForInsights();
int secure = mmsSmsDatabase.getSecureMessageCountForInsights();
if (insecure + secure == 0) return 0;
return Math.round(100f * (insecureCount / (float) (insecure + secure)));