summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Dmitri Plotnikov <dplotnikov@google.com> 2025-05-16 16:51:28 -0700
committer Kampalus <kampalus@protonmail.ch> 2025-09-18 09:09:51 +0200
commitb8656dd442b32cc25b6467f045ca24198a26e11f (patch)
treea72a01d47340ad916c36525e32da301371fcacef
parentd603ff6d17067f9653ccd4c8825019f591ae7dd7 (diff)
[SP 2025-09-01] Prevent non-system ShutdownActivity from being launched by BatteryService
Bug: 380885270 Test: adb shell dumpsys battery set temp 1001 Flag: EXEMPT bug fix (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:8cda6fda96c420588a5f8f5112522cfde14659b4) Merged-In: I6c00b47d424d81712bd9634c31de4b7d2e9cbe31 Change-Id: I6c00b47d424d81712bd9634c31de4b7d2e9cbe31
-rw-r--r--services/core/java/com/android/server/BatteryService.java76
1 files changed, 51 insertions, 25 deletions
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index 4cf17ae3984d..9ba032b4df8e 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -34,6 +34,9 @@ import android.app.BroadcastOptions;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
+import android.content.pm.ResolveInfo;
import android.database.ContentObserver;
import android.hardware.health.HealthInfo;
import android.hardware.health.V2_1.BatteryCapacityLevel;
@@ -54,6 +57,7 @@ import android.os.IBinder;
import android.os.Looper;
import android.os.OsProtoEnums;
import android.os.PowerManager;
+import android.os.Process;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ServiceManager;
@@ -89,6 +93,7 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayDeque;
import java.util.ArrayList;
+import java.util.List;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.concurrent.CopyOnWriteArraySet;
@@ -631,41 +636,62 @@ public final class BatteryService extends SystemService {
// shut down gracefully if our battery is critically low and we are not powered.
// wait until the system has booted before attempting to display the shutdown dialog.
if (shouldShutdownLocked()) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- if (mActivityManagerInternal.isSystemReady()) {
- Intent intent = new Intent(Intent.ACTION_REQUEST_SHUTDOWN);
- intent.putExtra(Intent.EXTRA_KEY_CONFIRM, false);
- intent.putExtra(Intent.EXTRA_REASON,
- PowerManager.SHUTDOWN_LOW_BATTERY);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- mContext.startActivityAsUser(intent, UserHandle.CURRENT);
- }
- }
- });
+ Intent intent = new Intent(Intent.ACTION_REQUEST_SHUTDOWN);
+ intent.putExtra(Intent.EXTRA_KEY_CONFIRM, false);
+ intent.putExtra(Intent.EXTRA_REASON,
+ PowerManager.SHUTDOWN_LOW_BATTERY);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mHandler.post(() -> startShutdownActivity(intent));
}
}
+
private void shutdownIfOverTempLocked() {
// shut down gracefully if temperature is too high (> 68.0C by default)
// wait until the system has booted before attempting to display the
// shutdown dialog.
if (mHealthInfo.batteryTemperatureTenthsCelsius > mShutdownBatteryTemperature) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- if (mActivityManagerInternal.isSystemReady()) {
- Intent intent = new Intent(Intent.ACTION_REQUEST_SHUTDOWN);
- intent.putExtra(Intent.EXTRA_KEY_CONFIRM, false);
- intent.putExtra(Intent.EXTRA_REASON,
- PowerManager.SHUTDOWN_BATTERY_THERMAL_STATE);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- mContext.startActivityAsUser(intent, UserHandle.CURRENT);
- }
+ Intent intent = new Intent(Intent.ACTION_REQUEST_SHUTDOWN);
+ intent.putExtra(Intent.EXTRA_KEY_CONFIRM, false);
+ intent.putExtra(Intent.EXTRA_REASON,
+ PowerManager.SHUTDOWN_BATTERY_THERMAL_STATE);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mHandler.post(() -> startShutdownActivity(intent));
+ }
+ }
+
+ private void startShutdownActivity(Intent intent) {
+ if (!mActivityManagerInternal.isSystemReady()) {
+ return;
+ }
+
+ PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class);
+ if (pmi == null) {
+ return;
+ }
+
+ // Find a target activity for the shutdown request that has android.permission.SHUTDOWN
+ List<ResolveInfo> resolveInfos = pmi.queryIntentActivities(intent, null, 0, Process.myUid(),
+ mActivityManagerInternal.getCurrentUserId());
+ if (resolveInfos != null) {
+ for (int i = 0; i < resolveInfos.size(); i++) {
+ ResolveInfo ri = resolveInfos.get(i);
+ if (ri.activityInfo == null || ri.activityInfo.applicationInfo == null) {
+ continue;
}
- });
+
+ if (mContext.checkPermission(android.Manifest.permission.SHUTDOWN, 0,
+ ri.activityInfo.applicationInfo.uid) != PackageManager.PERMISSION_GRANTED) {
+ Slog.w(TAG, "Shutdown activity " + ri.activityInfo.getComponentName()
+ + " does not have permission " + android.Manifest.permission.SHUTDOWN);
+ continue;
+ }
+
+ intent.setComponent(ri.activityInfo.getComponentName());
+ break;
+ }
}
+ mContext.startActivityAsUser(intent, UserHandle.CURRENT);
}
/**