summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Chun-Wei Wang <wangchun@google.com> 2022-12-08 06:40:18 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2022-12-08 06:40:18 +0000
commit0f8c32e2a03a48e56f3f688fa24302d62518c3bd (patch)
treefa4e3a11e8a0cf96a11346c96b06f4a48b72006b
parent49c87efa8b8a6ca5045d17ae24d55f10b82b2ea7 (diff)
parent8396fa6d8203249b21478f3716dfc324979ba287 (diff)
Merge changes from topic "install_constraints"
* changes: Include bounded services when calculating package dependency Implement AppStateHelper
-rw-r--r--core/java/android/app/ActivityManagerInternal.java5
-rw-r--r--services/core/java/com/android/server/am/ActiveServices.java31
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java7
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java4
-rw-r--r--services/core/java/com/android/server/pm/AppStateHelper.java59
5 files changed, 98 insertions, 8 deletions
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index f62190a7e6ca..c51e8aee61f0 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -902,4 +902,9 @@ public abstract class ActivityManagerInternal {
*/
public abstract void registerNetworkPolicyUidObserver(@NonNull IUidObserver observer,
int which, int cutpoint, @NonNull String callingPackage);
+
+ /**
+ * Return all client package names of a service.
+ */
+ public abstract ArraySet<String> getClientPackages(String servicePackageName);
}
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index e47bd449ccee..35b3db8a6332 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -7719,4 +7719,35 @@ public final class ActiveServices {
Slog.e(TAG, "stopForegroundServiceDelegateLocked delegate does not exist");
}
}
+
+ private static void getClientPackages(ServiceRecord sr, ArraySet<String> output) {
+ var connections = sr.getConnections();
+ for (int conni = connections.size() - 1; conni >= 0; conni--) {
+ var connl = connections.valueAt(conni);
+ for (int i = 0, size = connl.size(); i < size; i++) {
+ var conn = connl.get(i);
+ if (conn.binding.client != null) {
+ output.add(conn.binding.client.info.packageName);
+ }
+ }
+ }
+ }
+
+ /**
+ * Return all client package names of a service.
+ */
+ ArraySet<String> getClientPackagesLocked(@NonNull String servicePackageName) {
+ var results = new ArraySet<String>();
+ int[] users = mAm.mUserController.getUsers();
+ for (int ui = 0; ui < users.length; ui++) {
+ ArrayMap<ComponentName, ServiceRecord> alls = getServicesLocked(users[ui]);
+ for (int i = 0, size = alls.size(); i < size; i++) {
+ ServiceRecord sr = alls.valueAt(i);
+ if (sr.name.getPackageName().equals(servicePackageName)) {
+ getClientPackages(sr, results);
+ }
+ }
+ }
+ return results;
+ }
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 699a622efe55..b8a982a40e84 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -18191,6 +18191,13 @@ public class ActivityManagerService extends IActivityManager.Stub
mServices.stopForegroundServiceDelegateLocked(connection);
}
}
+
+ @Override
+ public ArraySet<String> getClientPackages(String servicePackageName) {
+ synchronized (ActivityManagerService.this) {
+ return mServices.getClientPackagesLocked(servicePackageName);
+ }
+ }
}
long inputDispatchingTimedOut(int pid, final boolean aboveSystem, TimeoutRecord timeoutRecord) {
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index aa8ee3d2d8aa..58cf7efb7cda 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -11427,8 +11427,8 @@ public class AudioService extends IAudioService.Stub
}
public List<AudioRecordingConfiguration> getActiveRecordingConfigurations() {
- final boolean isPrivileged =
- (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission(
+ final boolean isPrivileged = Binder.getCallingUid() == Process.SYSTEM_UID
+ || (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission(
android.Manifest.permission.MODIFY_AUDIO_ROUTING));
return mRecordMonitor.getActiveRecordingConfigurations(isPrivileged);
}
diff --git a/services/core/java/com/android/server/pm/AppStateHelper.java b/services/core/java/com/android/server/pm/AppStateHelper.java
index 9ea350f265b6..e6e8212ac16a 100644
--- a/services/core/java/com/android/server/pm/AppStateHelper.java
+++ b/services/core/java/com/android/server/pm/AppStateHelper.java
@@ -16,15 +16,22 @@
package com.android.server.pm;
+import static android.media.AudioAttributes.USAGE_VOICE_COMMUNICATION;
+import static android.media.AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING;
+
import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
+import android.app.ActivityManagerInternal;
import android.content.Context;
+import android.media.AudioManager;
import android.media.IAudioService;
import android.os.ServiceManager;
+import android.telecom.TelecomManager;
import android.text.TextUtils;
import android.util.ArraySet;
import com.android.internal.util.ArrayUtils;
+import com.android.server.LocalServices;
import java.util.ArrayList;
import java.util.List;
@@ -72,6 +79,43 @@ public class AppStateHelper {
}
/**
+ * True if any app is using voice communication.
+ */
+ private boolean hasVoiceCall() {
+ var am = mContext.getSystemService(AudioManager.class);
+ try {
+ for (var apc : am.getActivePlaybackConfigurations()) {
+ if (!apc.isActive()) {
+ continue;
+ }
+ var usage = apc.getAudioAttributes().getUsage();
+ if (usage == USAGE_VOICE_COMMUNICATION
+ || usage == USAGE_VOICE_COMMUNICATION_SIGNALLING) {
+ return true;
+ }
+ }
+ } catch (Exception ignore) {
+ }
+ return false;
+ }
+
+ /**
+ * True if the app is recording audio.
+ */
+ private boolean isRecordingAudio(String packageName) {
+ var am = mContext.getSystemService(AudioManager.class);
+ try {
+ for (var arc : am.getActiveRecordingConfigurations()) {
+ if (TextUtils.equals(arc.getClientPackageName(), packageName)) {
+ return true;
+ }
+ }
+ } catch (Exception ignore) {
+ }
+ return false;
+ }
+
+ /**
* True if the app is in the foreground.
*/
private boolean isAppForeground(String packageName) {
@@ -89,8 +133,7 @@ public class AppStateHelper {
* True if the app is playing/recording audio.
*/
private boolean hasActiveAudio(String packageName) {
- // TODO(b/235306967): also check recording
- return hasAudioFocus(packageName);
+ return hasAudioFocus(packageName) || isRecordingAudio(packageName);
}
/**
@@ -143,16 +186,16 @@ public class AppStateHelper {
* True if there is an ongoing phone call.
*/
public boolean isInCall() {
- // To be implemented
- return false;
+ // TelecomManager doesn't handle the case where some apps don't implement ConnectionService.
+ // We check apps using voice communication to detect if the device is in call.
+ var tm = mContext.getSystemService(TelecomManager.class);
+ return tm.isInCall() || hasVoiceCall();
}
/**
* Returns a list of packages which depend on {@code packageNames}. These are the packages
* that will be affected when updating {@code packageNames} and should participate in
* the evaluation of install constraints.
- *
- * TODO(b/235306967): Also include bounded services as dependency.
*/
public List<String> getDependencyPackages(List<String> packageNames) {
var results = new ArraySet<String>();
@@ -167,6 +210,10 @@ public class AppStateHelper {
}
}
}
+ var amInternal = LocalServices.getService(ActivityManagerInternal.class);
+ for (var packageName : packageNames) {
+ results.addAll(amInternal.getClientPackages(packageName));
+ }
return new ArrayList<>(results);
}
}