From 169ebe7ac176ab6372303c3f0f5cd5cd251403d2 Mon Sep 17 00:00:00 2001 From: Docile-Alligator <25734209+Docile-Alligator@users.noreply.github.com> Date: Mon, 28 Oct 2024 12:38:17 -0400 Subject: Move workers to the worker package. --- .../infinityforreddit/AppComponent.java | 2 + .../infinityforreddit/MaterialYouWorker.java | 55 ---- .../infinityforreddit/PullNotificationWorker.java | 275 -------------------- .../infinityforreddit/activities/MainActivity.java | 2 +- .../WallpaperChangeReceiver.java | 2 +- .../settings/NotificationPreferenceFragment.java | 2 +- .../worker/MaterialYouWorker.java | 57 +++++ .../worker/PullNotificationWorker.java | 278 +++++++++++++++++++++ 8 files changed, 340 insertions(+), 333 deletions(-) delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/MaterialYouWorker.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/PullNotificationWorker.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/worker/MaterialYouWorker.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/worker/PullNotificationWorker.java diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java index fcacd2b8..db5c9cee 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java @@ -104,6 +104,8 @@ import ml.docilealligator.infinityforreddit.settings.SecurityPreferenceFragment; import ml.docilealligator.infinityforreddit.settings.ThemePreferenceFragment; import ml.docilealligator.infinityforreddit.settings.TranslationFragment; import ml.docilealligator.infinityforreddit.settings.VideoPreferenceFragment; +import ml.docilealligator.infinityforreddit.worker.MaterialYouWorker; +import ml.docilealligator.infinityforreddit.worker.PullNotificationWorker; @Singleton @Component(modules = {AppModule.class, NetworkModule.class}) diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/MaterialYouWorker.java b/app/src/main/java/ml/docilealligator/infinityforreddit/MaterialYouWorker.java deleted file mode 100644 index 1cc8ba8b..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/MaterialYouWorker.java +++ /dev/null @@ -1,55 +0,0 @@ -package ml.docilealligator.infinityforreddit; - -import android.content.Context; -import android.content.SharedPreferences; - -import androidx.annotation.NonNull; -import androidx.work.Worker; -import androidx.work.WorkerParameters; - -import javax.inject.Inject; -import javax.inject.Named; - -import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.utils.MaterialYouUtils; -import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; - -public class MaterialYouWorker extends Worker { - public static final String UNIQUE_WORKER_NAME = "MYWT"; - - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - @Named("light_theme") - SharedPreferences lightThemeSharedPreferences; - @Inject - @Named("dark_theme") - SharedPreferences darkThemeSharedPreferences; - @Inject - @Named("amoled_theme") - SharedPreferences amoledThemeSharedPreferences; - @Inject - RedditDataRoomDatabase redditDataRoomDatabase; - @Inject - CustomThemeWrapper customThemeWrapper; - private final Context context; - - public MaterialYouWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) { - super(context, workerParams); - this.context = context; - ((Infinity) context.getApplicationContext()).getAppComponent().inject(this); - } - - @NonNull - @Override - public Result doWork() { - if (mSharedPreferences.getBoolean(SharedPreferencesUtils.ENABLE_MATERIAL_YOU, false)) { - MaterialYouUtils.changeThemeSync(context, redditDataRoomDatabase, - customThemeWrapper, lightThemeSharedPreferences, darkThemeSharedPreferences, - amoledThemeSharedPreferences); - } - - return Result.success(); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PullNotificationWorker.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PullNotificationWorker.java deleted file mode 100644 index f8fbcdaf..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/PullNotificationWorker.java +++ /dev/null @@ -1,275 +0,0 @@ -package ml.docilealligator.infinityforreddit; - -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.net.Uri; -import android.os.Build; - -import androidx.annotation.NonNull; -import androidx.core.app.NotificationCompat; -import androidx.core.app.NotificationManagerCompat; -import androidx.work.Worker; -import androidx.work.WorkerParameters; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.inject.Inject; -import javax.inject.Named; - -import ml.docilealligator.infinityforreddit.account.Account; -import ml.docilealligator.infinityforreddit.activities.InboxActivity; -import ml.docilealligator.infinityforreddit.activities.LinkResolverActivity; -import ml.docilealligator.infinityforreddit.apis.RedditAPI; -import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.message.FetchMessage; -import ml.docilealligator.infinityforreddit.message.Message; -import ml.docilealligator.infinityforreddit.message.ParseMessage; -import ml.docilealligator.infinityforreddit.utils.APIUtils; -import ml.docilealligator.infinityforreddit.utils.JSONUtils; -import ml.docilealligator.infinityforreddit.utils.NotificationUtils; -import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; -import retrofit2.Call; -import retrofit2.Response; -import retrofit2.Retrofit; - -public class PullNotificationWorker extends Worker { - public static final String UNIQUE_WORKER_NAME = "PNWT"; - @Inject - @Named("oauth_without_authenticator") - Retrofit mOauthWithoutAuthenticatorRetrofit; - @Inject - @Named("no_oauth") - Retrofit mRetrofit; - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - @Named("current_account") - SharedPreferences mCurrentAccountSharedPreferences; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - private final Context context; - - public PullNotificationWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) { - super(context, workerParams); - this.context = context; - ((Infinity) context.getApplicationContext()).getAppComponent().inject(this); - } - - @NonNull - @Override - public Result doWork() { - NotificationManagerCompat notificationManager = NotificationUtils.getNotificationManager(context); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && !notificationManager.areNotificationsEnabled()) { - return Result.success(); - } - - try { - List accounts = mRedditDataRoomDatabase.accountDao().getAllAccounts(); - int color = mCustomThemeWrapper.getColorPrimaryLightTheme(); - for (int accountIndex = 0; accountIndex < accounts.size(); accountIndex++) { - Account account = accounts.get(accountIndex); - - String accountName = account.getAccountName(); - - Response response = fetchMessages(account, 1); - - if (response != null && response.isSuccessful() && response.body() != null) { - String responseBody = response.body(); - JSONArray messageArray = new JSONObject(responseBody).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); - ArrayList messages = ParseMessage.parseMessages(messageArray, - context.getResources().getConfiguration().locale, FetchMessage.MESSAGE_TYPE_NOTIFICATION); - - if (!messages.isEmpty()) { - NotificationCompat.Builder summaryBuilder = NotificationUtils.buildSummaryNotification(context, - notificationManager, accountName, - context.getString(R.string.notification_new_messages, messages.size()), - NotificationUtils.CHANNEL_ID_NEW_MESSAGES, NotificationUtils.CHANNEL_NEW_MESSAGES, - NotificationUtils.getAccountGroupName(accountName), color); - - NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle(); - - int messageSize = Math.min(messages.size(), 20); - long lastNotificationTime = mSharedPreferences.getLong(SharedPreferencesUtils.PULL_NOTIFICATION_TIME, -1L); - boolean hasValidMessage = false; - - long currentTime = Calendar.getInstance().getTimeInMillis(); - mSharedPreferences.edit().putLong(SharedPreferencesUtils.PULL_NOTIFICATION_TIME, currentTime).apply(); - - int pendingIntentFlags = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE : PendingIntent.FLAG_UPDATE_CURRENT; - for (int messageIndex = messageSize - 1; messageIndex >= 0; messageIndex--) { - Message message = messages.get(messageIndex); - if (message.getTimeUTC() <= lastNotificationTime) { - continue; - } - - hasValidMessage = true; - - inboxStyle.addLine(message.getAuthor() + " " + message.getBody()); - - String kind = message.getKind(); - String title; - String summary; - if (kind.equals(Message.TYPE_COMMENT) || kind.equals(Message.TYPE_LINK)) { - title = message.getAuthor(); - summary = message.getSubject().substring(0, 1).toUpperCase() + message.getSubject().substring(1); - } else { - title = message.getTitle() == null || message.getTitle().equals("") ? message.getSubject() : message.getTitle(); - if (kind.equals(Message.TYPE_ACCOUNT)) { - summary = context.getString(R.string.notification_summary_account); - } else if (kind.equals(Message.TYPE_MESSAGE)) { - summary = context.getString(R.string.notification_summary_message); - } else if (kind.equals(Message.TYPE_SUBREDDIT)) { - summary = context.getString(R.string.notification_summary_subreddit); - } else { - summary = context.getString(R.string.notification_summary_award); - } - } - - NotificationCompat.Builder builder = NotificationUtils.buildNotification(notificationManager, - context, title, message.getBody(), summary, - NotificationUtils.CHANNEL_ID_NEW_MESSAGES, - NotificationUtils.CHANNEL_NEW_MESSAGES, - NotificationUtils.getAccountGroupName(accountName), color); - - if (kind.equals(Message.TYPE_COMMENT)) { - Intent intent = new Intent(context, LinkResolverActivity.class); - Uri uri = Uri.parse(message.getContext()); - intent.setData(uri); - intent.putExtra(LinkResolverActivity.EXTRA_NEW_ACCOUNT_NAME, accountName); - intent.putExtra(LinkResolverActivity.EXTRA_MESSAGE_FULLNAME, message.getFullname()); - PendingIntent pendingIntent = PendingIntent.getActivity(context, accountIndex * 6, intent, pendingIntentFlags); - builder.setContentIntent(pendingIntent); - } else if (kind.equals(Message.TYPE_ACCOUNT)) { - Intent intent = new Intent(context, InboxActivity.class); - intent.putExtra(InboxActivity.EXTRA_NEW_ACCOUNT_NAME, accountName); - PendingIntent summaryPendingIntent = PendingIntent.getActivity(context, accountIndex * 6 + 1, intent, pendingIntentFlags); - builder.setContentIntent(summaryPendingIntent); - } else if (kind.equals(Message.TYPE_LINK)) { - Intent intent = new Intent(context, LinkResolverActivity.class); - Uri uri = Uri.parse(message.getContext()); - intent.setData(uri); - intent.putExtra(LinkResolverActivity.EXTRA_NEW_ACCOUNT_NAME, accountName); - intent.putExtra(LinkResolverActivity.EXTRA_MESSAGE_FULLNAME, message.getFullname()); - PendingIntent pendingIntent = PendingIntent.getActivity(context, accountIndex * 6 + 2, intent, pendingIntentFlags); - builder.setContentIntent(pendingIntent); - } else if (kind.equals(Message.TYPE_MESSAGE)) { - Intent intent = new Intent(context, InboxActivity.class); - intent.putExtra(InboxActivity.EXTRA_NEW_ACCOUNT_NAME, accountName); - intent.putExtra(InboxActivity.EXTRA_VIEW_MESSAGE, true); - PendingIntent summaryPendingIntent = PendingIntent.getActivity(context, accountIndex * 6 + 3, intent, pendingIntentFlags); - builder.setContentIntent(summaryPendingIntent); - } else if (kind.equals(Message.TYPE_SUBREDDIT)) { - Intent intent = new Intent(context, InboxActivity.class); - intent.putExtra(InboxActivity.EXTRA_NEW_ACCOUNT_NAME, accountName); - PendingIntent summaryPendingIntent = PendingIntent.getActivity(context, accountIndex * 6 + 4, intent, pendingIntentFlags); - builder.setContentIntent(summaryPendingIntent); - } else { - Intent intent = new Intent(context, InboxActivity.class); - intent.putExtra(InboxActivity.EXTRA_NEW_ACCOUNT_NAME, accountName); - PendingIntent summaryPendingIntent = PendingIntent.getActivity(context, accountIndex * 6 + 5, intent, pendingIntentFlags); - builder.setContentIntent(summaryPendingIntent); - } - notificationManager.notify(NotificationUtils.getNotificationIdUnreadMessage(accountIndex, messageIndex), builder.build()); - } - - if (hasValidMessage) { - inboxStyle.setBigContentTitle(context.getString(R.string.notification_new_messages, messages.size())) - .setSummaryText(accountName); - - summaryBuilder.setStyle(inboxStyle); - - Intent summaryIntent = new Intent(context, InboxActivity.class); - summaryIntent.putExtra(InboxActivity.EXTRA_NEW_ACCOUNT_NAME, accountName); - PendingIntent summaryPendingIntent = PendingIntent.getActivity(context, accountIndex * 6 + 6, summaryIntent, pendingIntentFlags); - summaryBuilder.setContentIntent(summaryPendingIntent); - - notificationManager.notify(NotificationUtils.getSummaryIdUnreadMessage(accountIndex), summaryBuilder.build()); - } - } else { - return Result.success(); - } - } else { - return Result.retry(); - } - } - } catch (IOException | JSONException e) { - e.printStackTrace(); - return Result.retry(); - } - return Result.success(); - } - - private Response fetchMessages(Account account, int retryCount) throws IOException, JSONException { - if (retryCount < 0) { - return null; - } - - Call call = mOauthWithoutAuthenticatorRetrofit.create(RedditAPI.class) - .getMessages(APIUtils.getOAuthHeader(account.getAccessToken()), - FetchMessage.WHERE_UNREAD, null); - Response response = call.execute(); - - if (response.isSuccessful()) { - return response; - } else { - if (response.code() == 401) { - String accessToken = refreshAccessToken(account); - if (!accessToken.equals("")) { - account.setAccessToken(accessToken); - return fetchMessages(account, retryCount - 1); - } - - } - return null; - } - } - - private String refreshAccessToken(Account account) { - String refreshToken = account.getRefreshToken(); - - RedditAPI api = mRetrofit.create(RedditAPI.class); - - Map params = new HashMap<>(); - params.put(APIUtils.GRANT_TYPE_KEY, APIUtils.GRANT_TYPE_REFRESH_TOKEN); - params.put(APIUtils.REFRESH_TOKEN_KEY, refreshToken); - - Call accessTokenCall = api.getAccessToken(APIUtils.getHttpBasicAuthHeader(), params); - try { - Response response = accessTokenCall.execute(); - if (response.isSuccessful() && response.body() != null) { - JSONObject jsonObject = new JSONObject(response.body()); - String newAccessToken = jsonObject.getString(APIUtils.ACCESS_TOKEN_KEY); - String newRefreshToken = jsonObject.has(APIUtils.REFRESH_TOKEN_KEY) ? jsonObject.getString(APIUtils.REFRESH_TOKEN_KEY) : null; - if (newRefreshToken == null) { - mRedditDataRoomDatabase.accountDao().updateAccessToken(account.getAccountName(), newAccessToken); - } else { - mRedditDataRoomDatabase.accountDao().updateAccessTokenAndRefreshToken(account.getAccountName(), newAccessToken, newRefreshToken); - } - if (mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_NAME, Account.ANONYMOUS_ACCOUNT).equals(account.getAccountName())) { - mCurrentAccountSharedPreferences.edit().putString(SharedPreferencesUtils.ACCESS_TOKEN, newAccessToken).apply(); - } - return newAccessToken; - } - return ""; - } catch (IOException | JSONException e) { - e.printStackTrace(); - } - - return ""; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/MainActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/MainActivity.java index d86b862f..0e92206a 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/MainActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/MainActivity.java @@ -68,7 +68,7 @@ import javax.inject.Named; import ml.docilealligator.infinityforreddit.thing.FetchSubscribedThing; import ml.docilealligator.infinityforreddit.Infinity; import ml.docilealligator.infinityforreddit.post.MarkPostAsReadInterface; -import ml.docilealligator.infinityforreddit.PullNotificationWorker; +import ml.docilealligator.infinityforreddit.worker.PullNotificationWorker; import ml.docilealligator.infinityforreddit.R; import ml.docilealligator.infinityforreddit.RecyclerViewContentScrollingInterface; import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/broadcastreceivers/WallpaperChangeReceiver.java b/app/src/main/java/ml/docilealligator/infinityforreddit/broadcastreceivers/WallpaperChangeReceiver.java index 2a5efc9b..238d339a 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/broadcastreceivers/WallpaperChangeReceiver.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/broadcastreceivers/WallpaperChangeReceiver.java @@ -9,7 +9,7 @@ import androidx.work.ExistingWorkPolicy; import androidx.work.OneTimeWorkRequest; import androidx.work.WorkManager; -import ml.docilealligator.infinityforreddit.MaterialYouWorker; +import ml.docilealligator.infinityforreddit.worker.MaterialYouWorker; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; public class WallpaperChangeReceiver extends BroadcastReceiver { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/NotificationPreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/NotificationPreferenceFragment.java index 7ba9e869..1d351edc 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/NotificationPreferenceFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/NotificationPreferenceFragment.java @@ -29,7 +29,7 @@ import javax.inject.Inject; import javax.inject.Named; import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.PullNotificationWorker; +import ml.docilealligator.infinityforreddit.worker.PullNotificationWorker; import ml.docilealligator.infinityforreddit.R; import ml.docilealligator.infinityforreddit.customviews.CustomFontPreferenceFragmentCompat; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/worker/MaterialYouWorker.java b/app/src/main/java/ml/docilealligator/infinityforreddit/worker/MaterialYouWorker.java new file mode 100644 index 00000000..792bc2ed --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/worker/MaterialYouWorker.java @@ -0,0 +1,57 @@ +package ml.docilealligator.infinityforreddit.worker; + +import android.content.Context; +import android.content.SharedPreferences; + +import androidx.annotation.NonNull; +import androidx.work.Worker; +import androidx.work.WorkerParameters; + +import javax.inject.Inject; +import javax.inject.Named; + +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.utils.MaterialYouUtils; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +public class MaterialYouWorker extends Worker { + public static final String UNIQUE_WORKER_NAME = "MYWT"; + + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + @Named("light_theme") + SharedPreferences lightThemeSharedPreferences; + @Inject + @Named("dark_theme") + SharedPreferences darkThemeSharedPreferences; + @Inject + @Named("amoled_theme") + SharedPreferences amoledThemeSharedPreferences; + @Inject + RedditDataRoomDatabase redditDataRoomDatabase; + @Inject + CustomThemeWrapper customThemeWrapper; + private final Context context; + + public MaterialYouWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) { + super(context, workerParams); + this.context = context; + ((Infinity) context.getApplicationContext()).getAppComponent().inject(this); + } + + @NonNull + @Override + public Result doWork() { + if (mSharedPreferences.getBoolean(SharedPreferencesUtils.ENABLE_MATERIAL_YOU, false)) { + MaterialYouUtils.changeThemeSync(context, redditDataRoomDatabase, + customThemeWrapper, lightThemeSharedPreferences, darkThemeSharedPreferences, + amoledThemeSharedPreferences); + } + + return Result.success(); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/worker/PullNotificationWorker.java b/app/src/main/java/ml/docilealligator/infinityforreddit/worker/PullNotificationWorker.java new file mode 100644 index 00000000..ef8c81fd --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/worker/PullNotificationWorker.java @@ -0,0 +1,278 @@ +package ml.docilealligator.infinityforreddit.worker; + +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.net.Uri; +import android.os.Build; + +import androidx.annotation.NonNull; +import androidx.core.app.NotificationCompat; +import androidx.core.app.NotificationManagerCompat; +import androidx.work.Worker; +import androidx.work.WorkerParameters; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.inject.Inject; +import javax.inject.Named; + +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.account.Account; +import ml.docilealligator.infinityforreddit.activities.InboxActivity; +import ml.docilealligator.infinityforreddit.activities.LinkResolverActivity; +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.message.FetchMessage; +import ml.docilealligator.infinityforreddit.message.Message; +import ml.docilealligator.infinityforreddit.message.ParseMessage; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import ml.docilealligator.infinityforreddit.utils.JSONUtils; +import ml.docilealligator.infinityforreddit.utils.NotificationUtils; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import retrofit2.Call; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class PullNotificationWorker extends Worker { + public static final String UNIQUE_WORKER_NAME = "PNWT"; + @Inject + @Named("oauth_without_authenticator") + Retrofit mOauthWithoutAuthenticatorRetrofit; + @Inject + @Named("no_oauth") + Retrofit mRetrofit; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + @Named("current_account") + SharedPreferences mCurrentAccountSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private final Context context; + + public PullNotificationWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) { + super(context, workerParams); + this.context = context; + ((Infinity) context.getApplicationContext()).getAppComponent().inject(this); + } + + @NonNull + @Override + public Result doWork() { + NotificationManagerCompat notificationManager = NotificationUtils.getNotificationManager(context); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && !notificationManager.areNotificationsEnabled()) { + return Result.success(); + } + + try { + List accounts = mRedditDataRoomDatabase.accountDao().getAllAccounts(); + int color = mCustomThemeWrapper.getColorPrimaryLightTheme(); + for (int accountIndex = 0; accountIndex < accounts.size(); accountIndex++) { + Account account = accounts.get(accountIndex); + + String accountName = account.getAccountName(); + + Response response = fetchMessages(account, 1); + + if (response != null && response.isSuccessful() && response.body() != null) { + String responseBody = response.body(); + JSONArray messageArray = new JSONObject(responseBody).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); + ArrayList messages = ParseMessage.parseMessages(messageArray, + context.getResources().getConfiguration().locale, FetchMessage.MESSAGE_TYPE_NOTIFICATION); + + if (!messages.isEmpty()) { + NotificationCompat.Builder summaryBuilder = NotificationUtils.buildSummaryNotification(context, + notificationManager, accountName, + context.getString(R.string.notification_new_messages, messages.size()), + NotificationUtils.CHANNEL_ID_NEW_MESSAGES, NotificationUtils.CHANNEL_NEW_MESSAGES, + NotificationUtils.getAccountGroupName(accountName), color); + + NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle(); + + int messageSize = Math.min(messages.size(), 20); + long lastNotificationTime = mSharedPreferences.getLong(SharedPreferencesUtils.PULL_NOTIFICATION_TIME, -1L); + boolean hasValidMessage = false; + + long currentTime = Calendar.getInstance().getTimeInMillis(); + mSharedPreferences.edit().putLong(SharedPreferencesUtils.PULL_NOTIFICATION_TIME, currentTime).apply(); + + int pendingIntentFlags = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE : PendingIntent.FLAG_UPDATE_CURRENT; + for (int messageIndex = messageSize - 1; messageIndex >= 0; messageIndex--) { + Message message = messages.get(messageIndex); + if (message.getTimeUTC() <= lastNotificationTime) { + continue; + } + + hasValidMessage = true; + + inboxStyle.addLine(message.getAuthor() + " " + message.getBody()); + + String kind = message.getKind(); + String title; + String summary; + if (kind.equals(Message.TYPE_COMMENT) || kind.equals(Message.TYPE_LINK)) { + title = message.getAuthor(); + summary = message.getSubject().substring(0, 1).toUpperCase() + message.getSubject().substring(1); + } else { + title = message.getTitle() == null || message.getTitle().equals("") ? message.getSubject() : message.getTitle(); + if (kind.equals(Message.TYPE_ACCOUNT)) { + summary = context.getString(R.string.notification_summary_account); + } else if (kind.equals(Message.TYPE_MESSAGE)) { + summary = context.getString(R.string.notification_summary_message); + } else if (kind.equals(Message.TYPE_SUBREDDIT)) { + summary = context.getString(R.string.notification_summary_subreddit); + } else { + summary = context.getString(R.string.notification_summary_award); + } + } + + NotificationCompat.Builder builder = NotificationUtils.buildNotification(notificationManager, + context, title, message.getBody(), summary, + NotificationUtils.CHANNEL_ID_NEW_MESSAGES, + NotificationUtils.CHANNEL_NEW_MESSAGES, + NotificationUtils.getAccountGroupName(accountName), color); + + if (kind.equals(Message.TYPE_COMMENT)) { + Intent intent = new Intent(context, LinkResolverActivity.class); + Uri uri = Uri.parse(message.getContext()); + intent.setData(uri); + intent.putExtra(LinkResolverActivity.EXTRA_NEW_ACCOUNT_NAME, accountName); + intent.putExtra(LinkResolverActivity.EXTRA_MESSAGE_FULLNAME, message.getFullname()); + PendingIntent pendingIntent = PendingIntent.getActivity(context, accountIndex * 6, intent, pendingIntentFlags); + builder.setContentIntent(pendingIntent); + } else if (kind.equals(Message.TYPE_ACCOUNT)) { + Intent intent = new Intent(context, InboxActivity.class); + intent.putExtra(InboxActivity.EXTRA_NEW_ACCOUNT_NAME, accountName); + PendingIntent summaryPendingIntent = PendingIntent.getActivity(context, accountIndex * 6 + 1, intent, pendingIntentFlags); + builder.setContentIntent(summaryPendingIntent); + } else if (kind.equals(Message.TYPE_LINK)) { + Intent intent = new Intent(context, LinkResolverActivity.class); + Uri uri = Uri.parse(message.getContext()); + intent.setData(uri); + intent.putExtra(LinkResolverActivity.EXTRA_NEW_ACCOUNT_NAME, accountName); + intent.putExtra(LinkResolverActivity.EXTRA_MESSAGE_FULLNAME, message.getFullname()); + PendingIntent pendingIntent = PendingIntent.getActivity(context, accountIndex * 6 + 2, intent, pendingIntentFlags); + builder.setContentIntent(pendingIntent); + } else if (kind.equals(Message.TYPE_MESSAGE)) { + Intent intent = new Intent(context, InboxActivity.class); + intent.putExtra(InboxActivity.EXTRA_NEW_ACCOUNT_NAME, accountName); + intent.putExtra(InboxActivity.EXTRA_VIEW_MESSAGE, true); + PendingIntent summaryPendingIntent = PendingIntent.getActivity(context, accountIndex * 6 + 3, intent, pendingIntentFlags); + builder.setContentIntent(summaryPendingIntent); + } else if (kind.equals(Message.TYPE_SUBREDDIT)) { + Intent intent = new Intent(context, InboxActivity.class); + intent.putExtra(InboxActivity.EXTRA_NEW_ACCOUNT_NAME, accountName); + PendingIntent summaryPendingIntent = PendingIntent.getActivity(context, accountIndex * 6 + 4, intent, pendingIntentFlags); + builder.setContentIntent(summaryPendingIntent); + } else { + Intent intent = new Intent(context, InboxActivity.class); + intent.putExtra(InboxActivity.EXTRA_NEW_ACCOUNT_NAME, accountName); + PendingIntent summaryPendingIntent = PendingIntent.getActivity(context, accountIndex * 6 + 5, intent, pendingIntentFlags); + builder.setContentIntent(summaryPendingIntent); + } + notificationManager.notify(NotificationUtils.getNotificationIdUnreadMessage(accountIndex, messageIndex), builder.build()); + } + + if (hasValidMessage) { + inboxStyle.setBigContentTitle(context.getString(R.string.notification_new_messages, messages.size())) + .setSummaryText(accountName); + + summaryBuilder.setStyle(inboxStyle); + + Intent summaryIntent = new Intent(context, InboxActivity.class); + summaryIntent.putExtra(InboxActivity.EXTRA_NEW_ACCOUNT_NAME, accountName); + PendingIntent summaryPendingIntent = PendingIntent.getActivity(context, accountIndex * 6 + 6, summaryIntent, pendingIntentFlags); + summaryBuilder.setContentIntent(summaryPendingIntent); + + notificationManager.notify(NotificationUtils.getSummaryIdUnreadMessage(accountIndex), summaryBuilder.build()); + } + } else { + return Result.success(); + } + } else { + return Result.retry(); + } + } + } catch (IOException | JSONException e) { + e.printStackTrace(); + return Result.retry(); + } + return Result.success(); + } + + private Response fetchMessages(Account account, int retryCount) throws IOException, JSONException { + if (retryCount < 0) { + return null; + } + + Call call = mOauthWithoutAuthenticatorRetrofit.create(RedditAPI.class) + .getMessages(APIUtils.getOAuthHeader(account.getAccessToken()), + FetchMessage.WHERE_UNREAD, null); + Response response = call.execute(); + + if (response.isSuccessful()) { + return response; + } else { + if (response.code() == 401) { + String accessToken = refreshAccessToken(account); + if (!accessToken.equals("")) { + account.setAccessToken(accessToken); + return fetchMessages(account, retryCount - 1); + } + + } + return null; + } + } + + private String refreshAccessToken(Account account) { + String refreshToken = account.getRefreshToken(); + + RedditAPI api = mRetrofit.create(RedditAPI.class); + + Map params = new HashMap<>(); + params.put(APIUtils.GRANT_TYPE_KEY, APIUtils.GRANT_TYPE_REFRESH_TOKEN); + params.put(APIUtils.REFRESH_TOKEN_KEY, refreshToken); + + Call accessTokenCall = api.getAccessToken(APIUtils.getHttpBasicAuthHeader(), params); + try { + Response response = accessTokenCall.execute(); + if (response.isSuccessful() && response.body() != null) { + JSONObject jsonObject = new JSONObject(response.body()); + String newAccessToken = jsonObject.getString(APIUtils.ACCESS_TOKEN_KEY); + String newRefreshToken = jsonObject.has(APIUtils.REFRESH_TOKEN_KEY) ? jsonObject.getString(APIUtils.REFRESH_TOKEN_KEY) : null; + if (newRefreshToken == null) { + mRedditDataRoomDatabase.accountDao().updateAccessToken(account.getAccountName(), newAccessToken); + } else { + mRedditDataRoomDatabase.accountDao().updateAccessTokenAndRefreshToken(account.getAccountName(), newAccessToken, newRefreshToken); + } + if (mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_NAME, Account.ANONYMOUS_ACCOUNT).equals(account.getAccountName())) { + mCurrentAccountSharedPreferences.edit().putString(SharedPreferencesUtils.ACCESS_TOKEN, newAccessToken).apply(); + } + return newAccessToken; + } + return ""; + } catch (IOException | JSONException e) { + e.printStackTrace(); + } + + return ""; + } +} -- cgit v1.2.3