Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0f8c32e2 authored by Chun-Wei Wang's avatar Chun-Wei Wang Committed by Android (Google) Code Review
Browse files

Merge changes from topic "install_constraints"

* changes:
  Include bounded services when calculating package dependency
  Implement AppStateHelper
parents 49c87efa 8396fa6d
Loading
Loading
Loading
Loading
+5 −0
Original line number Original line Diff line number Diff line
@@ -902,4 +902,9 @@ public abstract class ActivityManagerInternal {
     */
     */
    public abstract void registerNetworkPolicyUidObserver(@NonNull IUidObserver observer,
    public abstract void registerNetworkPolicyUidObserver(@NonNull IUidObserver observer,
            int which, int cutpoint, @NonNull String callingPackage);
            int which, int cutpoint, @NonNull String callingPackage);

    /**
     * Return all client package names of a service.
     */
    public abstract ArraySet<String> getClientPackages(String servicePackageName);
}
}
+31 −0
Original line number Original line Diff line number Diff line
@@ -7719,4 +7719,35 @@ public final class ActiveServices {
            Slog.e(TAG, "stopForegroundServiceDelegateLocked delegate does not exist");
            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;
    }
}
}
+7 −0
Original line number Original line Diff line number Diff line
@@ -18191,6 +18191,13 @@ public class ActivityManagerService extends IActivityManager.Stub
                mServices.stopForegroundServiceDelegateLocked(connection);
                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) {
    long inputDispatchingTimedOut(int pid, final boolean aboveSystem, TimeoutRecord timeoutRecord) {
+2 −2
Original line number Original line Diff line number Diff line
@@ -11427,8 +11427,8 @@ public class AudioService extends IAudioService.Stub
    }
    }
    public List<AudioRecordingConfiguration> getActiveRecordingConfigurations() {
    public List<AudioRecordingConfiguration> getActiveRecordingConfigurations() {
        final boolean isPrivileged =
        final boolean isPrivileged = Binder.getCallingUid() == Process.SYSTEM_UID
                (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission(
                || (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission(
                        android.Manifest.permission.MODIFY_AUDIO_ROUTING));
                        android.Manifest.permission.MODIFY_AUDIO_ROUTING));
        return mRecordMonitor.getActiveRecordingConfigurations(isPrivileged);
        return mRecordMonitor.getActiveRecordingConfigurations(isPrivileged);
    }
    }
+53 −6
Original line number Original line Diff line number Diff line
@@ -16,15 +16,22 @@


package com.android.server.pm;
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;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.app.ActivityManagerInternal;
import android.content.Context;
import android.content.Context;
import android.media.AudioManager;
import android.media.IAudioService;
import android.media.IAudioService;
import android.os.ServiceManager;
import android.os.ServiceManager;
import android.telecom.TelecomManager;
import android.text.TextUtils;
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.ArraySet;


import com.android.internal.util.ArrayUtils;
import com.android.internal.util.ArrayUtils;
import com.android.server.LocalServices;


import java.util.ArrayList;
import java.util.ArrayList;
import java.util.List;
import java.util.List;
@@ -71,6 +78,43 @@ public class AppStateHelper {
        return false;
        return false;
    }
    }


    /**
     * 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.
     * True if the app is in the foreground.
     */
     */
@@ -89,8 +133,7 @@ public class AppStateHelper {
     * True if the app is playing/recording audio.
     * True if the app is playing/recording audio.
     */
     */
    private boolean hasActiveAudio(String packageName) {
    private boolean hasActiveAudio(String packageName) {
        // TODO(b/235306967): also check recording
        return hasAudioFocus(packageName) || isRecordingAudio(packageName);
        return hasAudioFocus(packageName);
    }
    }


    /**
    /**
@@ -143,16 +186,16 @@ public class AppStateHelper {
     * True if there is an ongoing phone call.
     * True if there is an ongoing phone call.
     */
     */
    public boolean isInCall() {
    public boolean isInCall() {
        // To be implemented
        // TelecomManager doesn't handle the case where some apps don't implement ConnectionService.
        return false;
        // 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
     * 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
     * that will be affected when updating {@code packageNames} and should participate in
     * the evaluation of install constraints.
     * the evaluation of install constraints.
     *
     * TODO(b/235306967): Also include bounded services as dependency.
     */
     */
    public List<String> getDependencyPackages(List<String> packageNames) {
    public List<String> getDependencyPackages(List<String> packageNames) {
        var results = new ArraySet<String>();
        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);
        return new ArrayList<>(results);
    }
    }
}
}