Skip to content

Commit 1ad0eba

Browse files
committed
ApplicationInfoHelper handles DeadSystemException
Add this new helper class to handle DeadSystemException to encapsulate these error handling details with the Android API. Also added a caching layer as a DeadSystemException could happen anytime and caching gives us better stability and performance.
1 parent 769ff37 commit 1ad0eba

File tree

6 files changed

+87
-43
lines changed

6 files changed

+87
-43
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.onesignal
2+
3+
import android.annotation.TargetApi
4+
import android.content.Context
5+
import android.content.pm.ApplicationInfo
6+
import android.content.pm.PackageManager
7+
import android.os.DeadSystemException
8+
import android.util.AndroidException
9+
10+
class ApplicationInfoHelper {
11+
companion object {
12+
// Safe to cache as nothing can change the app while it is running.
13+
private var cachedInfo: ApplicationInfo? = null
14+
15+
@TargetApi(24)
16+
fun getInfo(context: Context): ApplicationInfo? {
17+
if (cachedInfo != null) {
18+
return cachedInfo
19+
}
20+
21+
val packageManager = context.packageManager
22+
return try {
23+
// Using this instead of context.applicationInfo as it's metaData is always null
24+
cachedInfo = packageManager.getApplicationInfo(
25+
context.packageName,
26+
PackageManager.GET_META_DATA,
27+
)
28+
cachedInfo
29+
} catch (e: AndroidException) {
30+
// Suppressing DeadSystemException as the app is already dying for
31+
// another reason and allowing this exception to bubble up would
32+
// create a red herring for app developers. We still re-throw
33+
// others, as we don't want to silently hide other issues.
34+
if (e !is DeadSystemException) {
35+
throw e
36+
}
37+
null
38+
}
39+
}
40+
}
41+
}

OneSignalSDK/onesignal/src/main/java/com/onesignal/BadgeCountUpdater.java

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929

3030
import android.content.Context;
3131
import android.content.pm.ApplicationInfo;
32-
import android.content.pm.PackageManager;
3332
import android.database.Cursor;
3433
import android.os.Build;
3534
import android.os.Bundle;
@@ -51,19 +50,20 @@ private static boolean areBadgeSettingsEnabled(Context context) {
5150
if (badgesEnabled != -1)
5251
return (badgesEnabled == 1);
5352

54-
try {
55-
ApplicationInfo ai = context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
56-
Bundle bundle = ai.metaData;
57-
if (bundle != null) {
58-
String defaultStr = bundle.getString("com.onesignal.BadgeCount");
59-
badgesEnabled = "DISABLE".equals(defaultStr) ? 0 : 1;
60-
}
61-
else
62-
badgesEnabled = 1;
63-
} catch (PackageManager.NameNotFoundException e) {
53+
ApplicationInfo ai = ApplicationInfoHelper.Companion.getInfo(context);
54+
if (ai == null) {
6455
badgesEnabled = 0;
65-
OneSignal.Log(OneSignal.LOG_LEVEL.ERROR, "Error reading meta-data tag 'com.onesignal.BadgeCount'. Disabling badge setting.", e);
56+
OneSignal.Log(OneSignal.LOG_LEVEL.ERROR, "Error reading meta-data tag 'com.onesignal.BadgeCount'. Disabling badge setting.");
57+
return false;
58+
}
59+
60+
Bundle bundle = ai.metaData;
61+
if (bundle != null) {
62+
String defaultStr = bundle.getString("com.onesignal.BadgeCount");
63+
badgesEnabled = "DISABLE".equals(defaultStr) ? 0 : 1;
6664
}
65+
else
66+
badgesEnabled = 1;
6767

6868
return (badgesEnabled == 1);
6969
}

OneSignalSDK/onesignal/src/main/java/com/onesignal/GenerateNotification.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import android.content.ContentValues;
3434
import android.content.Context;
3535
import android.content.Intent;
36+
import android.content.pm.ApplicationInfo;
3637
import android.content.res.Resources;
3738
import android.database.Cursor;
3839
import android.graphics.Bitmap;
@@ -133,14 +134,23 @@ static void isRunningOnMainThreadCheck() {
133134
if (OSUtils.isRunningOnMainThread())
134135
throw new OSThrowable.OSMainThreadException("Process for showing a notification should never been done on Main Thread!");
135136
}
137+
138+
private static CharSequence getApplicationLabel() {
139+
ApplicationInfo applicationInfo = ApplicationInfoHelper.Companion.getInfo(currentContext);
140+
if (applicationInfo == null) {
141+
return "";
142+
}
143+
144+
return currentContext.getPackageManager().getApplicationLabel(applicationInfo);
145+
}
136146

137147
private static CharSequence getTitle(JSONObject fcmJson) {
138148
CharSequence title = fcmJson.optString("title", null);
139149

140150
if (title != null)
141151
return title;
142152

143-
return currentContext.getPackageManager().getApplicationLabel(currentContext.getApplicationInfo());
153+
return getApplicationLabel();
144154
}
145155

146156
private static PendingIntent getNewDismissActionPendingIntent(int requestCode, Intent intent) {
@@ -615,7 +625,7 @@ private static void createSummaryNotification(OSNotificationGenerationJob notifi
615625
// Default small and large icons are used instead of the payload options to enforce this.
616626
summaryBuilder.setContentIntent(summaryContentIntent)
617627
.setDeleteIntent(summaryDeleteIntent)
618-
.setContentTitle(currentContext.getPackageManager().getApplicationLabel(currentContext.getApplicationInfo()))
628+
.setContentTitle(getApplicationLabel())
619629
.setContentText(summaryMessage)
620630
.setNumber(notificationCount)
621631
.setSmallIcon(getDefaultSmallIconId())
@@ -735,7 +745,7 @@ private static void createGrouplessSummaryNotification(
735745
// Default small and large icons are used instead of the payload options to enforce this.
736746
summaryBuilder.setContentIntent(summaryContentIntent)
737747
.setDeleteIntent(summaryDeleteIntent)
738-
.setContentTitle(currentContext.getPackageManager().getApplicationLabel(currentContext.getApplicationInfo()))
748+
.setContentTitle(getApplicationLabel())
739749
.setContentText(summaryMessage)
740750
.setNumber(grouplessNotifCount)
741751
.setSmallIcon(getDefaultSmallIconId())

OneSignalSDK/onesignal/src/main/java/com/onesignal/NavigateToAndroidSettingsForNotifications.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,10 @@ object NavigateToAndroidSettingsForNotifications {
3838

3939
// for Android 5-7
4040
intent.putExtra("app_package", context.getPackageName())
41-
intent.putExtra("app_uid", context.getApplicationInfo().uid)
41+
val applicationInfo = ApplicationInfoHelper.getInfo(context)
42+
if (applicationInfo != null) {
43+
intent.putExtra("app_uid", applicationInfo.uid)
44+
}
4245

4346
// for Android 8 and above
4447
intent.putExtra("android.provider.extra.APP_PACKAGE", context.getPackageName())

OneSignalSDK/onesignal/src/main/java/com/onesignal/OSUtils.java

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -416,15 +416,11 @@ String getCarrierName() {
416416
}
417417

418418
static Bundle getManifestMetaBundle(Context context) {
419-
ApplicationInfo ai;
420-
try {
421-
ai = context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
422-
return ai.metaData;
423-
} catch (PackageManager.NameNotFoundException e) {
424-
Log(OneSignal.LOG_LEVEL.ERROR, "Manifest application info not found", e);
419+
ApplicationInfo ai = ApplicationInfoHelper.Companion.getInfo(context);
420+
if (ai == null) {
421+
return null;
425422
}
426-
427-
return null;
423+
return ai.metaData;
428424
}
429425

430426
static boolean getManifestMetaBoolean(Context context, String metaName) {
@@ -496,16 +492,11 @@ static void runOnMainThreadDelayed(Runnable runnable, int delay) {
496492
}
497493

498494
static int getTargetSdkVersion(Context context) {
499-
String packageName = context.getPackageName();
500-
PackageManager packageManager = context.getPackageManager();
501-
try {
502-
ApplicationInfo applicationInfo = packageManager.getApplicationInfo(packageName, 0);
503-
return applicationInfo.targetSdkVersion;
504-
} catch (PackageManager.NameNotFoundException e) {
505-
e.printStackTrace();
495+
ApplicationInfo applicationInfo = ApplicationInfoHelper.Companion.getInfo(context);
496+
if (applicationInfo == null) {
497+
return Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1;
506498
}
507-
508-
return Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1;
499+
return applicationInfo.targetSdkVersion;
509500
}
510501

511502
static boolean isValidResourceName(String name) {

OneSignalSDK/onesignal/src/main/java/com/onesignal/OneSignal.java

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -921,17 +921,16 @@ private static void setupContextListeners(boolean wasAppContextNull) {
921921
}
922922

923923
private static void setupPrivacyConsent(Context context) {
924-
try {
925-
ApplicationInfo ai = context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
926-
Bundle bundle = ai.metaData;
927-
928-
// Read the current privacy consent setting from AndroidManifest.xml
929-
String requireSetting = bundle.getString("com.onesignal.PrivacyConsent");
930-
if (requireSetting != null)
931-
setRequiresUserPrivacyConsent("ENABLE".equalsIgnoreCase(requireSetting));
932-
} catch (Throwable t) {
933-
t.printStackTrace();
924+
ApplicationInfo ai = ApplicationInfoHelper.Companion.getInfo(context);
925+
if (ai == null) {
926+
return;
934927
}
928+
Bundle bundle = ai.metaData;
929+
930+
// Read the current privacy consent setting from AndroidManifest.xml
931+
String requireSetting = bundle.getString("com.onesignal.PrivacyConsent");
932+
if (requireSetting != null)
933+
setRequiresUserPrivacyConsent("ENABLE".equalsIgnoreCase(requireSetting));
935934
}
936935

937936
private static void handleAppIdChange() {

0 commit comments

Comments
 (0)