Skip to content

Commit 1f6a3b7

Browse files
authored
Merge pull request #1937 from OneSignal/player-model/handle-DeadSystemException
[Player model] Handle DeadSystemException
2 parents 48860d2 + dd73d5b commit 1f6a3b7

10 files changed

+293
-131
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/GooglePlayServicesUpgradePrompt.java

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import android.app.AlertDialog;
55
import android.app.PendingIntent;
66
import android.content.DialogInterface;
7-
import android.content.pm.PackageInfo;
87
import android.content.pm.PackageManager;
98

109
import com.google.android.gms.common.GoogleApiAvailability;
@@ -13,18 +12,23 @@
1312

1413
class GooglePlayServicesUpgradePrompt {
1514
private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 9_000;
16-
1715
private static boolean isGooglePlayStoreInstalled() {
18-
try {
19-
PackageManager pm = OneSignal.appContext.getPackageManager();
20-
PackageInfo info = pm.getPackageInfo(GoogleApiAvailability.GOOGLE_PLAY_SERVICES_PACKAGE, PackageManager.GET_META_DATA);
21-
String label = (String) info.applicationInfo.loadLabel(pm);
22-
return (!label.equals("Market"));
23-
} catch (PackageManager.NameNotFoundException e) {
24-
// Google Play Store might not be installed, ignore exception if so
16+
GetPackageInfoResult result =
17+
PackageInfoHelper.Companion.getInfo(
18+
OneSignal.appContext,
19+
GoogleApiAvailability.GOOGLE_PLAY_SERVICES_PACKAGE,
20+
PackageManager.GET_META_DATA
21+
);
22+
if (!result.getSuccessful()) {
23+
return false;
24+
}
25+
if (result.getPackageInfo() == null) {
26+
return false;
2527
}
2628

27-
return false;
29+
PackageManager pm = OneSignal.appContext.getPackageManager();
30+
String label = (String) result.getPackageInfo().applicationInfo.loadLabel(pm);
31+
return !label.equals("Market");
2832
}
2933

3034
static void showUpdateGPSDialog() {

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

Lines changed: 67 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
package com.onesignal;
2929

3030
import android.content.Context;
31-
import android.content.pm.PackageInfo;
3231
import android.content.pm.PackageManager;
3332
import android.location.Location;
3433
import android.os.Build;
@@ -221,48 +220,54 @@ static void getLocation(Context context, boolean promptLocation, boolean fallbac
221220
startGetLocation();
222221
} else { // Android 6.0+
223222
if (locationFinePermission != PackageManager.PERMISSION_GRANTED) {
224-
try {
225-
PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_PERMISSIONS);
226-
List<String> permissionList = Arrays.asList(packageInfo.requestedPermissions);
227-
OneSignal.PromptActionResult result = OneSignal.PromptActionResult.PERMISSION_DENIED;
223+
GetPackageInfoResult packageResult =
224+
PackageInfoHelper.Companion.getInfo(
225+
context,
226+
context.getPackageName(),
227+
PackageManager.GET_PERMISSIONS
228+
);
229+
230+
if (!packageResult.getSuccessful() || packageResult.getPackageInfo() == null) {
231+
sendAndClearPromptHandlers(promptLocation, OneSignal.PromptActionResult.ERROR);
232+
return;
233+
}
234+
235+
List<String> permissionList = Arrays.asList(packageResult.getPackageInfo().requestedPermissions);
236+
OneSignal.PromptActionResult result = OneSignal.PromptActionResult.PERMISSION_DENIED;
228237

229-
if (permissionList.contains("android.permission.ACCESS_FINE_LOCATION")) {
230-
// ACCESS_FINE_LOCATION permission defined on Manifest, prompt for permission
238+
if (permissionList.contains("android.permission.ACCESS_FINE_LOCATION")) {
239+
// ACCESS_FINE_LOCATION permission defined on Manifest, prompt for permission
240+
// If permission already given prompt will return positive, otherwise will prompt again or show settings
241+
requestPermission = "android.permission.ACCESS_FINE_LOCATION";
242+
} else if (permissionList.contains("android.permission.ACCESS_COARSE_LOCATION")) {
243+
if (locationCoarsePermission != PackageManager.PERMISSION_GRANTED) {
244+
// ACCESS_COARSE_LOCATION permission defined on Manifest, prompt for permission
231245
// If permission already given prompt will return positive, otherwise will prompt again or show settings
232-
requestPermission = "android.permission.ACCESS_FINE_LOCATION";
233-
} else if (permissionList.contains("android.permission.ACCESS_COARSE_LOCATION")) {
234-
if (locationCoarsePermission != PackageManager.PERMISSION_GRANTED) {
235-
// ACCESS_COARSE_LOCATION permission defined on Manifest, prompt for permission
236-
// If permission already given prompt will return positive, otherwise will prompt again or show settings
237-
requestPermission = "android.permission.ACCESS_COARSE_LOCATION";
238-
} else if (Build.VERSION.SDK_INT >= 29 && permissionList.contains("android.permission.ACCESS_BACKGROUND_LOCATION")) {
239-
// ACCESS_BACKGROUND_LOCATION permission defined on Manifest, prompt for permission
240-
requestPermission = "android.permission.ACCESS_BACKGROUND_LOCATION";
241-
}
242-
} else {
243-
OneSignal.onesignalLog(OneSignal.LOG_LEVEL.INFO, "Location permissions not added on AndroidManifest file");
244-
result = OneSignal.PromptActionResult.LOCATION_PERMISSIONS_MISSING_MANIFEST;
246+
requestPermission = "android.permission.ACCESS_COARSE_LOCATION";
247+
} else if (Build.VERSION.SDK_INT >= 29 && permissionList.contains("android.permission.ACCESS_BACKGROUND_LOCATION")) {
248+
// ACCESS_BACKGROUND_LOCATION permission defined on Manifest, prompt for permission
249+
requestPermission = "android.permission.ACCESS_BACKGROUND_LOCATION";
245250
}
251+
} else {
252+
OneSignal.onesignalLog(OneSignal.LOG_LEVEL.INFO, "Location permissions not added on AndroidManifest file");
253+
result = OneSignal.PromptActionResult.LOCATION_PERMISSIONS_MISSING_MANIFEST;
254+
}
246255

247-
// We handle the following cases:
248-
// 1 - If needed and available then prompt for permissions
249-
// - Request permission can be ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION
250-
// 2 - If the permission were already granted then start getting location
251-
// 3 - If permission wasn't granted then trigger fail flow
252-
//
253-
// For each case, we call the prompt handlers
254-
if (requestPermission != null && promptLocation) {
255-
LocationPermissionController.INSTANCE.prompt(fallbackToSettings, requestPermission);
256-
} else if (locationCoarsePermission == PackageManager.PERMISSION_GRANTED) {
257-
sendAndClearPromptHandlers(promptLocation, OneSignal.PromptActionResult.PERMISSION_GRANTED);
258-
startGetLocation();
259-
} else {
260-
sendAndClearPromptHandlers(promptLocation, result);
261-
fireFailedComplete();
262-
}
263-
} catch (PackageManager.NameNotFoundException e) {
264-
sendAndClearPromptHandlers(promptLocation, OneSignal.PromptActionResult.ERROR);
265-
e.printStackTrace();
256+
// We handle the following cases:
257+
// 1 - If needed and available then prompt for permissions
258+
// - Request permission can be ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION
259+
// 2 - If the permission were already granted then start getting location
260+
// 3 - If permission wasn't granted then trigger fail flow
261+
//
262+
// For each case, we call the prompt handlers
263+
if (requestPermission != null && promptLocation) {
264+
LocationPermissionController.INSTANCE.prompt(fallbackToSettings, requestPermission);
265+
} else if (locationCoarsePermission == PackageManager.PERMISSION_GRANTED) {
266+
sendAndClearPromptHandlers(promptLocation, OneSignal.PromptActionResult.PERMISSION_GRANTED);
267+
startGetLocation();
268+
} else {
269+
sendAndClearPromptHandlers(promptLocation, result);
270+
fireFailedComplete();
266271
}
267272
} else if (Build.VERSION.SDK_INT >= 29 && locationBackgroundPermission != PackageManager.PERMISSION_GRANTED) {
268273
backgroundLocationPermissionLogic(context, promptLocation, fallbackToSettings);
@@ -279,25 +284,31 @@ static void getLocation(Context context, boolean promptLocation, boolean fallbac
279284
* If background permission is asked at the same time as fine and coarse then both permission request are ignored
280285
* */
281286
private static void backgroundLocationPermissionLogic(Context context, boolean promptLocation, boolean fallbackToSettings) {
282-
try {
283-
PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_PERMISSIONS);
284-
List<String> permissionList = Arrays.asList(packageInfo.requestedPermissions);
287+
GetPackageInfoResult result =
288+
PackageInfoHelper.Companion.getInfo(
289+
context,
290+
context.getPackageName(),
291+
PackageManager.GET_PERMISSIONS
292+
);
293+
294+
if (!result.getSuccessful() || result.getPackageInfo() == null) {
295+
sendAndClearPromptHandlers(promptLocation, OneSignal.PromptActionResult.ERROR);
296+
return;
297+
}
285298

286-
if (permissionList.contains("android.permission.ACCESS_BACKGROUND_LOCATION")) {
287-
// ACCESS_BACKGROUND_LOCATION permission defined on Manifest, prompt for permission
288-
requestPermission = "android.permission.ACCESS_BACKGROUND_LOCATION";
289-
}
299+
List<String> permissionList = Arrays.asList(result.getPackageInfo().requestedPermissions);
290300

291-
if (requestPermission != null && promptLocation) {
292-
LocationPermissionController.INSTANCE.prompt(fallbackToSettings, requestPermission);
293-
} else {
294-
// Fine permission already granted
295-
sendAndClearPromptHandlers(promptLocation, OneSignal.PromptActionResult.PERMISSION_GRANTED);
296-
startGetLocation();
297-
}
298-
} catch (PackageManager.NameNotFoundException e) {
299-
sendAndClearPromptHandlers(promptLocation, OneSignal.PromptActionResult.ERROR);
300-
e.printStackTrace();
301+
if (permissionList.contains("android.permission.ACCESS_BACKGROUND_LOCATION")) {
302+
// ACCESS_BACKGROUND_LOCATION permission defined on Manifest, prompt for permission
303+
requestPermission = "android.permission.ACCESS_BACKGROUND_LOCATION";
304+
}
305+
306+
if (requestPermission != null && promptLocation) {
307+
LocationPermissionController.INSTANCE.prompt(fallbackToSettings, requestPermission);
308+
} else {
309+
// Fine permission already granted
310+
sendAndClearPromptHandlers(promptLocation, OneSignal.PromptActionResult.PERMISSION_GRANTED);
311+
startGetLocation();
301312
}
302313
}
303314

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())

0 commit comments

Comments
 (0)