2929import androidx .annotation .NonNull ;
3030import androidx .annotation .RequiresApi ;
3131
32+ import com .microsoft .identity .common .logging .Logger ;
33+
34+ import java .util .Map ;
35+ import java .util .concurrent .ConcurrentHashMap ;
36+
3237/**
3338 * Wrapper class for PowerManager.
3439 */
@@ -38,6 +43,9 @@ public class PowerManagerWrapper {
3843 private static PowerManagerWrapper sInstance ;
3944
4045 private static final String UNKNOWN_STATUS = "Unknown" ;
46+
47+ // In-memory cache for battery optimization status (now stores String results)
48+ private final Map <String , String > batteryOptOutCache = new ConcurrentHashMap <>();
4149 /**
4250 * Set instance of PowerManagerWrapper.
4351 *
@@ -107,10 +115,6 @@ public String getDeviceIdleMode(@NonNull final Context context){
107115 @ NonNull
108116 public String getPowerOptimizationSettings (@ NonNull final Context context ){
109117 try {
110- if (Build .VERSION .SDK_INT < Build .VERSION_CODES .M ) {
111- return UNKNOWN_STATUS ;
112- }
113-
114118 final PowerManager powerManager = ((PowerManager ) context .getSystemService (Context .POWER_SERVICE ));
115119 if (powerManager .isIgnoringBatteryOptimizations (context .getPackageName ())){
116120 return "OptOut" ;
@@ -134,4 +138,34 @@ public String getPowerOptimizationSettings(@NonNull final Context context){
134138 public boolean isIgnoringBatteryOptimizations (final Context connectionContext ) {
135139 return ((PowerManager ) connectionContext .getSystemService (Context .POWER_SERVICE )).isIgnoringBatteryOptimizations (connectionContext .getPackageName ());
136140 }
141+
142+ /**
143+ * Checks if the app with the given package name is opted out from battery optimization.
144+ * Caches the result in memory using computeIfAbsent for thread safety.
145+ * Returns a string indicating the result or exception type.
146+ *
147+ * @param packageName The package name to check.
148+ * @param context The context to use for PowerManager.
149+ * @return "OptedOut" if the app is opted out, "NotOptedOut" if not, or exception type string.
150+ */
151+ public String isAppOptedOutFromBatteryOptimization (@ NonNull final String packageName , @ NonNull final Context context ) {
152+ return batteryOptOutCache .computeIfAbsent (packageName , key -> {
153+ try {
154+ final PowerManager powerManager = (PowerManager ) context .getSystemService (Context .POWER_SERVICE );
155+ if (powerManager .isIgnoringBatteryOptimizations (key )) {
156+ return "OptedOut" ;
157+ } else {
158+ return "NotOptedOut" ;
159+ }
160+ } catch (NullPointerException e ) {
161+ return "NullPointerException" ;
162+ } catch (SecurityException e ) {
163+ return "SecurityException" ;
164+ } catch (IllegalArgumentException e ) {
165+ return "IllegalArgumentException" ;
166+ } catch (Exception e ) {
167+ return "UnknownException" ;
168+ }
169+ });
170+ }
137171}
0 commit comments