Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Player model] Handle DeadSystemException #1937

Merged
merged 4 commits into from
Dec 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading