Skip to content

Commit

Permalink
Merge pull request #1937 from OneSignal/player-model/handle-DeadSyste…
Browse files Browse the repository at this point in the history
…mException

[Player model] Handle DeadSystemException
  • Loading branch information
jkasten2 authored Dec 14, 2023
2 parents 48860d2 + dd73d5b commit 1f6a3b7
Show file tree
Hide file tree
Showing 10 changed files with 293 additions and 131 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.onesignal

import android.annotation.TargetApi
import android.content.Context
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.os.DeadSystemException
import android.util.AndroidException

class ApplicationInfoHelper {
companion object {
// Safe to cache as nothing can change the app while it is running.
private var cachedInfo: ApplicationInfo? = null

@TargetApi(24)
fun getInfo(context: Context): ApplicationInfo? {
if (cachedInfo != null) {
return cachedInfo
}

val packageManager = context.packageManager
return try {
// Using this instead of context.applicationInfo as it's metaData is always null
cachedInfo = packageManager.getApplicationInfo(
context.packageName,
PackageManager.GET_META_DATA,
)
cachedInfo
} catch (e: AndroidException) {
// Suppressing DeadSystemException as the app is already dying for
// another reason and allowing this exception to bubble up would
// create a red herring for app developers. We still re-throw
// others, as we don't want to silently hide other issues.
if (e !is DeadSystemException) {
throw e
}
null
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.os.Build;
import android.os.Bundle;
Expand All @@ -51,19 +50,20 @@ private static boolean areBadgeSettingsEnabled(Context context) {
if (badgesEnabled != -1)
return (badgesEnabled == 1);

try {
ApplicationInfo ai = context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
Bundle bundle = ai.metaData;
if (bundle != null) {
String defaultStr = bundle.getString("com.onesignal.BadgeCount");
badgesEnabled = "DISABLE".equals(defaultStr) ? 0 : 1;
}
else
badgesEnabled = 1;
} catch (PackageManager.NameNotFoundException e) {
ApplicationInfo ai = ApplicationInfoHelper.Companion.getInfo(context);
if (ai == null) {
badgesEnabled = 0;
OneSignal.Log(OneSignal.LOG_LEVEL.ERROR, "Error reading meta-data tag 'com.onesignal.BadgeCount'. Disabling badge setting.", e);
OneSignal.Log(OneSignal.LOG_LEVEL.ERROR, "Error reading meta-data tag 'com.onesignal.BadgeCount'. Disabling badge setting.");
return false;
}

Bundle bundle = ai.metaData;
if (bundle != null) {
String defaultStr = bundle.getString("com.onesignal.BadgeCount");
badgesEnabled = "DISABLE".equals(defaultStr) ? 0 : 1;
}
else
badgesEnabled = 1;

return (badgesEnabled == 1);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
Expand Down Expand Up @@ -133,14 +134,23 @@ static void isRunningOnMainThreadCheck() {
if (OSUtils.isRunningOnMainThread())
throw new OSThrowable.OSMainThreadException("Process for showing a notification should never been done on Main Thread!");
}

private static CharSequence getApplicationLabel() {
ApplicationInfo applicationInfo = ApplicationInfoHelper.Companion.getInfo(currentContext);
if (applicationInfo == null) {
return "";
}

return currentContext.getPackageManager().getApplicationLabel(applicationInfo);
}

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

if (title != null)
return title;

return currentContext.getPackageManager().getApplicationLabel(currentContext.getApplicationInfo());
return getApplicationLabel();
}

private static PendingIntent getNewDismissActionPendingIntent(int requestCode, Intent intent) {
Expand Down Expand Up @@ -615,7 +625,7 @@ private static void createSummaryNotification(OSNotificationGenerationJob notifi
// Default small and large icons are used instead of the payload options to enforce this.
summaryBuilder.setContentIntent(summaryContentIntent)
.setDeleteIntent(summaryDeleteIntent)
.setContentTitle(currentContext.getPackageManager().getApplicationLabel(currentContext.getApplicationInfo()))
.setContentTitle(getApplicationLabel())
.setContentText(summaryMessage)
.setNumber(notificationCount)
.setSmallIcon(getDefaultSmallIconId())
Expand Down Expand Up @@ -735,7 +745,7 @@ private static void createGrouplessSummaryNotification(
// Default small and large icons are used instead of the payload options to enforce this.
summaryBuilder.setContentIntent(summaryContentIntent)
.setDeleteIntent(summaryDeleteIntent)
.setContentTitle(currentContext.getPackageManager().getApplicationLabel(currentContext.getApplicationInfo()))
.setContentTitle(getApplicationLabel())
.setContentText(summaryMessage)
.setNumber(grouplessNotifCount)
.setSmallIcon(getDefaultSmallIconId())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.content.DialogInterface;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;

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

class GooglePlayServicesUpgradePrompt {
private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 9_000;

private static boolean isGooglePlayStoreInstalled() {
try {
PackageManager pm = OneSignal.appContext.getPackageManager();
PackageInfo info = pm.getPackageInfo(GoogleApiAvailability.GOOGLE_PLAY_SERVICES_PACKAGE, PackageManager.GET_META_DATA);
String label = (String) info.applicationInfo.loadLabel(pm);
return (!label.equals("Market"));
} catch (PackageManager.NameNotFoundException e) {
// Google Play Store might not be installed, ignore exception if so
GetPackageInfoResult result =
PackageInfoHelper.Companion.getInfo(
OneSignal.appContext,
GoogleApiAvailability.GOOGLE_PLAY_SERVICES_PACKAGE,
PackageManager.GET_META_DATA
);
if (!result.getSuccessful()) {
return false;
}
if (result.getPackageInfo() == null) {
return false;
}

return false;
PackageManager pm = OneSignal.appContext.getPackageManager();
String label = (String) result.getPackageInfo().applicationInfo.loadLabel(pm);
return !label.equals("Market");
}

static void showUpdateGPSDialog() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
package com.onesignal;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Build;
Expand Down Expand Up @@ -221,48 +220,54 @@ static void getLocation(Context context, boolean promptLocation, boolean fallbac
startGetLocation();
} else { // Android 6.0+
if (locationFinePermission != PackageManager.PERMISSION_GRANTED) {
try {
PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_PERMISSIONS);
List<String> permissionList = Arrays.asList(packageInfo.requestedPermissions);
OneSignal.PromptActionResult result = OneSignal.PromptActionResult.PERMISSION_DENIED;
GetPackageInfoResult packageResult =
PackageInfoHelper.Companion.getInfo(
context,
context.getPackageName(),
PackageManager.GET_PERMISSIONS
);

if (!packageResult.getSuccessful() || packageResult.getPackageInfo() == null) {
sendAndClearPromptHandlers(promptLocation, OneSignal.PromptActionResult.ERROR);
return;
}

List<String> permissionList = Arrays.asList(packageResult.getPackageInfo().requestedPermissions);
OneSignal.PromptActionResult result = OneSignal.PromptActionResult.PERMISSION_DENIED;

if (permissionList.contains("android.permission.ACCESS_FINE_LOCATION")) {
// ACCESS_FINE_LOCATION permission defined on Manifest, prompt for permission
if (permissionList.contains("android.permission.ACCESS_FINE_LOCATION")) {
// ACCESS_FINE_LOCATION permission defined on Manifest, prompt for permission
// If permission already given prompt will return positive, otherwise will prompt again or show settings
requestPermission = "android.permission.ACCESS_FINE_LOCATION";
} else if (permissionList.contains("android.permission.ACCESS_COARSE_LOCATION")) {
if (locationCoarsePermission != PackageManager.PERMISSION_GRANTED) {
// ACCESS_COARSE_LOCATION permission defined on Manifest, prompt for permission
// If permission already given prompt will return positive, otherwise will prompt again or show settings
requestPermission = "android.permission.ACCESS_FINE_LOCATION";
} else if (permissionList.contains("android.permission.ACCESS_COARSE_LOCATION")) {
if (locationCoarsePermission != PackageManager.PERMISSION_GRANTED) {
// ACCESS_COARSE_LOCATION permission defined on Manifest, prompt for permission
// If permission already given prompt will return positive, otherwise will prompt again or show settings
requestPermission = "android.permission.ACCESS_COARSE_LOCATION";
} else if (Build.VERSION.SDK_INT >= 29 && permissionList.contains("android.permission.ACCESS_BACKGROUND_LOCATION")) {
// ACCESS_BACKGROUND_LOCATION permission defined on Manifest, prompt for permission
requestPermission = "android.permission.ACCESS_BACKGROUND_LOCATION";
}
} else {
OneSignal.onesignalLog(OneSignal.LOG_LEVEL.INFO, "Location permissions not added on AndroidManifest file");
result = OneSignal.PromptActionResult.LOCATION_PERMISSIONS_MISSING_MANIFEST;
requestPermission = "android.permission.ACCESS_COARSE_LOCATION";
} else if (Build.VERSION.SDK_INT >= 29 && permissionList.contains("android.permission.ACCESS_BACKGROUND_LOCATION")) {
// ACCESS_BACKGROUND_LOCATION permission defined on Manifest, prompt for permission
requestPermission = "android.permission.ACCESS_BACKGROUND_LOCATION";
}
} else {
OneSignal.onesignalLog(OneSignal.LOG_LEVEL.INFO, "Location permissions not added on AndroidManifest file");
result = OneSignal.PromptActionResult.LOCATION_PERMISSIONS_MISSING_MANIFEST;
}

// We handle the following cases:
// 1 - If needed and available then prompt for permissions
// - Request permission can be ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION
// 2 - If the permission were already granted then start getting location
// 3 - If permission wasn't granted then trigger fail flow
//
// For each case, we call the prompt handlers
if (requestPermission != null && promptLocation) {
LocationPermissionController.INSTANCE.prompt(fallbackToSettings, requestPermission);
} else if (locationCoarsePermission == PackageManager.PERMISSION_GRANTED) {
sendAndClearPromptHandlers(promptLocation, OneSignal.PromptActionResult.PERMISSION_GRANTED);
startGetLocation();
} else {
sendAndClearPromptHandlers(promptLocation, result);
fireFailedComplete();
}
} catch (PackageManager.NameNotFoundException e) {
sendAndClearPromptHandlers(promptLocation, OneSignal.PromptActionResult.ERROR);
e.printStackTrace();
// We handle the following cases:
// 1 - If needed and available then prompt for permissions
// - Request permission can be ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION
// 2 - If the permission were already granted then start getting location
// 3 - If permission wasn't granted then trigger fail flow
//
// For each case, we call the prompt handlers
if (requestPermission != null && promptLocation) {
LocationPermissionController.INSTANCE.prompt(fallbackToSettings, requestPermission);
} else if (locationCoarsePermission == PackageManager.PERMISSION_GRANTED) {
sendAndClearPromptHandlers(promptLocation, OneSignal.PromptActionResult.PERMISSION_GRANTED);
startGetLocation();
} else {
sendAndClearPromptHandlers(promptLocation, result);
fireFailedComplete();
}
} else if (Build.VERSION.SDK_INT >= 29 && locationBackgroundPermission != PackageManager.PERMISSION_GRANTED) {
backgroundLocationPermissionLogic(context, promptLocation, fallbackToSettings);
Expand All @@ -279,25 +284,31 @@ static void getLocation(Context context, boolean promptLocation, boolean fallbac
* If background permission is asked at the same time as fine and coarse then both permission request are ignored
* */
private static void backgroundLocationPermissionLogic(Context context, boolean promptLocation, boolean fallbackToSettings) {
try {
PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_PERMISSIONS);
List<String> permissionList = Arrays.asList(packageInfo.requestedPermissions);
GetPackageInfoResult result =
PackageInfoHelper.Companion.getInfo(
context,
context.getPackageName(),
PackageManager.GET_PERMISSIONS
);

if (!result.getSuccessful() || result.getPackageInfo() == null) {
sendAndClearPromptHandlers(promptLocation, OneSignal.PromptActionResult.ERROR);
return;
}

if (permissionList.contains("android.permission.ACCESS_BACKGROUND_LOCATION")) {
// ACCESS_BACKGROUND_LOCATION permission defined on Manifest, prompt for permission
requestPermission = "android.permission.ACCESS_BACKGROUND_LOCATION";
}
List<String> permissionList = Arrays.asList(result.getPackageInfo().requestedPermissions);

if (requestPermission != null && promptLocation) {
LocationPermissionController.INSTANCE.prompt(fallbackToSettings, requestPermission);
} else {
// Fine permission already granted
sendAndClearPromptHandlers(promptLocation, OneSignal.PromptActionResult.PERMISSION_GRANTED);
startGetLocation();
}
} catch (PackageManager.NameNotFoundException e) {
sendAndClearPromptHandlers(promptLocation, OneSignal.PromptActionResult.ERROR);
e.printStackTrace();
if (permissionList.contains("android.permission.ACCESS_BACKGROUND_LOCATION")) {
// ACCESS_BACKGROUND_LOCATION permission defined on Manifest, prompt for permission
requestPermission = "android.permission.ACCESS_BACKGROUND_LOCATION";
}

if (requestPermission != null && promptLocation) {
LocationPermissionController.INSTANCE.prompt(fallbackToSettings, requestPermission);
} else {
// Fine permission already granted
sendAndClearPromptHandlers(promptLocation, OneSignal.PromptActionResult.PERMISSION_GRANTED);
startGetLocation();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@ object NavigateToAndroidSettingsForNotifications {

// for Android 5-7
intent.putExtra("app_package", context.getPackageName())
intent.putExtra("app_uid", context.getApplicationInfo().uid)
val applicationInfo = ApplicationInfoHelper.getInfo(context)
if (applicationInfo != null) {
intent.putExtra("app_uid", applicationInfo.uid)
}

// for Android 8 and above
intent.putExtra("android.provider.extra.APP_PACKAGE", context.getPackageName())
Expand Down
Loading

0 comments on commit 1f6a3b7

Please sign in to comment.