diff options
| author | 2022-12-08 06:40:18 +0000 | |
|---|---|---|
| committer | 2022-12-08 06:40:18 +0000 | |
| commit | 0f8c32e2a03a48e56f3f688fa24302d62518c3bd (patch) | |
| tree | fa4e3a11e8a0cf96a11346c96b06f4a48b72006b | |
| parent | 49c87efa8b8a6ca5045d17ae24d55f10b82b2ea7 (diff) | |
| parent | 8396fa6d8203249b21478f3716dfc324979ba287 (diff) | |
Merge changes from topic "install_constraints"
* changes:
Include bounded services when calculating package dependency
Implement AppStateHelper
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); } } |