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

Commit 86cd001e authored by Makoto Onuki's avatar Makoto Onuki Committed by Android (Google) Code Review
Browse files

Merge "Have AudioService listen to DISALLOW_UNMUTE_MICROPHONE and"

parents 09530338 d45a4a2e
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -19,6 +19,17 @@ package android.os;
 * @hide Only for use within the system server.
 */
public abstract class UserManagerInternal {
    public interface UserRestrictionsListener {
        /**
         * Called when a user restriction changes.
         *
         * @param userId target user id
         * @param newRestrictions new user restrictions
         * @param prevRestrictions user restrictions that were previously set
         */
        void onUserRestrictionsChanged(int userId, Bundle newRestrictions, Bundle prevRestrictions);
    }

    /**
     * Lock that must be held when calling certain methods in this class.
     *
@@ -60,4 +71,13 @@ public abstract class UserManagerInternal {
     */
    public abstract void setBaseUserRestrictionsByDpmsForMigration(int userId,
            Bundle baseRestrictions);

    /** Return a user restriction. */
    public abstract boolean getUserRestriction(int userId, String key);

    /** Adds a listener to user restriction changes. */
    public abstract void addUserRestrictionsListener(UserRestrictionsListener listener);

    /** Remove a {@link UserRestrictionsListener}. */
    public abstract void removeUserRestrictionsListener(UserRestrictionsListener listener);
}
+78 −4
Original line number Diff line number Diff line
@@ -76,6 +76,7 @@ import android.media.audiopolicy.AudioPolicyConfig;
import android.media.audiopolicy.IAudioPolicyCallback;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
@@ -88,6 +89,8 @@ import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.UserManagerInternal;
import android.os.UserManagerInternal.UserRestrictionsListener;
import android.os.Vibrator;
import android.provider.Settings;
import android.provider.Settings.System;
@@ -397,6 +400,12 @@ public class AudioService extends IAudioService.Stub {
    // Broadcast receiver for device connections intent broadcasts
    private final BroadcastReceiver mReceiver = new AudioServiceBroadcastReceiver();

    /** Interface for UserManagerService. */
    private final UserManagerInternal mUserManagerInternal;

    private final UserRestrictionsListener mUserRestrictionsListener =
            new AudioServiceUserRestrictionsListener();

    // Devices currently connected
    // Use makeDeviceListKey() to make a unique key for this list.
    private class DeviceListSpec {
@@ -598,6 +607,8 @@ public class AudioService extends IAudioService.Stub {

        mPlatformType = AudioSystem.getPlatformType(context);

        mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);

        PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
        mAudioEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "handleAudioEvent");

@@ -694,6 +705,8 @@ public class AudioService extends IAudioService.Stub {
        context.registerReceiverAsUser(mReceiver, UserHandle.ALL, intentFilter, null, null);

        LocalServices.addService(AudioManagerInternal.class, new AudioServiceInternal());

        mUserManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener);
    }

    public void systemReady() {
@@ -1039,17 +1052,32 @@ public class AudioService extends IAudioService.Stub {
                System.MUTE_STREAMS_AFFECTED, AudioSystem.DEFAULT_MUTE_STREAMS_AFFECTED,
                UserHandle.USER_CURRENT);

        boolean masterMute = System.getIntForUser(cr, System.VOLUME_MASTER_MUTE,
                0, UserHandle.USER_CURRENT) == 1;
        final int currentUser = getCurrentUserId();

        // In addition to checking the system setting, also check the current user restriction.
        // Because of the delay before persisting VOLUME_MASTER_MUTE, there's a window where
        // DISALLOW_ADJUST_VOLUME will be ignored when it's set right before switching users.
        boolean masterMute = (System.getIntForUser(cr, System.VOLUME_MASTER_MUTE,
                0, UserHandle.USER_CURRENT) == 1)
                || mUserManagerInternal.getUserRestriction(
                    currentUser, UserManager.DISALLOW_ADJUST_VOLUME);
        if (mUseFixedVolume) {
            masterMute = false;
            AudioSystem.setMasterVolume(1.0f);
        }
        if (DEBUG_VOL) {
            Log.d(TAG, String.format("Master mute %s, user=%d", masterMute, currentUser));
        }
        AudioSystem.setMasterMute(masterMute);
        broadcastMasterMuteStatus(masterMute);

        boolean microphoneMute =
                System.getIntForUser(cr, System.MICROPHONE_MUTE, 0, UserHandle.USER_CURRENT) == 1;
                (System.getIntForUser(cr, System.MICROPHONE_MUTE, 0, UserHandle.USER_CURRENT) == 1)
                || mUserManagerInternal.getUserRestriction(
                        currentUser, UserManager.DISALLOW_UNMUTE_MICROPHONE);
        if (DEBUG_VOL) {
            Log.d(TAG, String.format("Mic mute %s, user=%d", microphoneMute, currentUser));
        }
        AudioSystem.muteMicrophone(microphoneMute);

        // Each stream will read its own persisted settings
@@ -1767,6 +1795,16 @@ public class AudioService extends IAudioService.Stub {
                != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        setMasterMuteInternalNoCallerCheck(mute, flags, userId);
    }

    private void setMasterMuteInternalNoCallerCheck(boolean mute, int flags, int userId) {
        if (DEBUG_VOL) {
            Log.d(TAG, String.format("Master mute %s, %d, user=%d", mute, flags, userId));
        }
        if (mUseFixedVolume) {
            return; // If using fixed volume, we don't mute.
        }
        if (getCurrentUserId() == userId) {
            if (mute != AudioSystem.getMasterMute()) {
                setSystemAudioMute(mute);
@@ -1841,7 +1879,8 @@ public class AudioService extends IAudioService.Stub {
        return mStreamVolumeAlias[AudioSystem.STREAM_SYSTEM];
    }

    /** @see AudioManager#setMicrophoneMute(boolean, int) */
    /** @see AudioManager#setMicrophoneMute(boolean) */
    @Override
    public void setMicrophoneMute(boolean on, String callingPackage, int userId) {
        // If we are being called by the system check for user we are going to change
        // so we handle user restrictions correctly.
@@ -1863,7 +1902,13 @@ public class AudioService extends IAudioService.Stub {
                != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        setMicrophoneMuteNoCallerCheck(on, userId);
    }

    private void setMicrophoneMuteNoCallerCheck(boolean on, int userId) {
        if (DEBUG_VOL) {
            Log.d(TAG, String.format("Mic mute %s, user=%d", on, userId));
        }
        // If mute is for current user actually mute, else just persist the setting
        // which will be loaded on user switch.
        if (getCurrentUserId() == userId) {
@@ -5116,6 +5161,35 @@ public class AudioService extends IAudioService.Stub {
        }
    } // end class AudioServiceBroadcastReceiver

    private class AudioServiceUserRestrictionsListener implements UserRestrictionsListener {

        @Override
        public void onUserRestrictionsChanged(int userId, Bundle newRestrictions,
                Bundle prevRestrictions) {
            // Update mic mute state.
            {
                final boolean wasRestricted =
                        prevRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_MICROPHONE);
                final boolean isRestricted =
                        newRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_MICROPHONE);
                if (wasRestricted != isRestricted) {
                    setMicrophoneMuteNoCallerCheck(isRestricted, userId);
                }
            }

            // Update speaker mute state.
            {
                final boolean wasRestricted =
                        prevRestrictions.getBoolean(UserManager.DISALLOW_ADJUST_VOLUME);
                final boolean isRestricted =
                        newRestrictions.getBoolean(UserManager.DISALLOW_ADJUST_VOLUME);
                if (wasRestricted != isRestricted) {
                    setMasterMuteInternalNoCallerCheck(isRestricted, /* flags =*/ 0, userId);
                }
            }
        }
    } // end class AudioServiceUserRestrictionsListener

    private void killBackgroundUserProcessesWithRecordAudioPermission(UserInfo oldUser) {
        PackageManager pm = mContext.getPackageManager();
        // Find the home activity of the user. It should not be killed to avoid expensive restart,
+57 −2
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.UserManagerInternal;
import android.os.UserManagerInternal.UserRestrictionsListener;
import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo;
import android.system.ErrnoException;
@@ -232,6 +233,10 @@ public class UserManagerService extends IUserManager.Stub {

    private final LocalService mLocalService;

    @GuardedBy("mUserRestrictionsListeners")
    private final ArrayList<UserRestrictionsListener> mUserRestrictionsListeners =
            new ArrayList<>();

    private static UserManagerService sInstance;

    public static UserManagerService getInstance() {
@@ -781,7 +786,14 @@ public class UserManagerService extends IUserManager.Stub {

    @GuardedBy("mRestrictionsLock")
    private void applyUserRestrictionsLR(int userId, Bundle newRestrictions) {
        final Bundle prevRestrictions = mAppliedUserRestrictions.get(userId);
        if (newRestrictions == null) {
            newRestrictions = Bundle.EMPTY;
        }

        Bundle prevRestrictions = mAppliedUserRestrictions.get(userId);
        if (prevRestrictions == null) {
            prevRestrictions = Bundle.EMPTY;
        }

        if (DBG) {
            Log.d(LOG_TAG, "applyUserRestrictionsRL userId=" + userId
@@ -797,12 +809,36 @@ public class UserManagerService extends IUserManager.Stub {
            Binder.restoreCallingIdentity(token);
        }

        UserRestrictionsUtils.applyUserRestrictions(
        UserRestrictionsUtils.applyUserRestrictionsLR(
                mContext, userId, newRestrictions, prevRestrictions);

        notifyUserRestrictionsListeners(userId, newRestrictions, prevRestrictions);

        mAppliedUserRestrictions.put(userId, new Bundle(newRestrictions));
    }

    private void notifyUserRestrictionsListeners(final int userId,
            Bundle newRestrictions, Bundle prevRestrictions) {

        final Bundle newRestrictionsFinal = new Bundle(newRestrictions);
        final Bundle prevRestrictionsFinal = new Bundle(prevRestrictions);

        mHandler.post(new Runnable() {
            @Override
            public void run() {
                final UserRestrictionsListener[] listeners;
                synchronized (mUserRestrictionsListeners) {
                    listeners = new UserRestrictionsListener[mUserRestrictionsListeners.size()];
                    mUserRestrictionsListeners.toArray(listeners);
                }
                for (int i = 0; i < listeners.length; i++) {
                    listeners[i].onUserRestrictionsChanged(userId,
                            newRestrictionsFinal, prevRestrictionsFinal);
                }
            }
        });
    }

    @GuardedBy("mRestrictionsLock")
    private void updateEffectiveUserRestrictionsLR(int userId) {
        updateUserRestrictionsInternalLR(null, userId);
@@ -2388,6 +2424,25 @@ public class UserManagerService extends IUserManager.Stub {
                }
            }
        }

        @Override
        public boolean getUserRestriction(int userId, String key) {
            return getUserRestrictions(userId).getBoolean(key);
        }

        @Override
        public void addUserRestrictionsListener(UserRestrictionsListener listener) {
            synchronized (mUserRestrictionsListeners) {
                mUserRestrictionsListeners.add(listener);
            }
        }

        @Override
        public void removeUserRestrictionsListener(UserRestrictionsListener listener) {
            synchronized (mUserRestrictionsListeners) {
                mUserRestrictionsListeners.remove(listener);
            }
        }
    }

    private class Shell extends ShellCommand {
+20 −25
Original line number Diff line number Diff line
@@ -18,19 +18,14 @@ package com.android.server.pm;

import com.google.android.collect.Sets;

import android.annotation.Nullable;
import android.content.ContentResolver;
import android.content.Context;
import android.media.IAudioService;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Slog;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlSerializer;
@@ -39,6 +34,11 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.util.Set;

/**
 * Utility methods for uesr restrictions.
 *
 * <p>See {@link UserManagerService} for the method suffixes.
 */
public class UserRestrictionsUtils {
    private static final String TAG = "UserRestrictionsUtils";

@@ -129,26 +129,31 @@ public class UserRestrictionsUtils {
    /**
     * Takes a new use restriction set and the previous set, and apply the restrictions that have
     * changed.
     *
     * <p>Note this method is called by {@link UserManagerService} while holding
     * {@code mRestrictionLock}. Be aware when calling into other services, which could cause
     * a deadlock.
     */
    public static void applyUserRestrictions(Context context, int userId,
            @Nullable Bundle newRestrictions, @Nullable Bundle prevRestrictions) {
        if (newRestrictions == null) {
            newRestrictions = Bundle.EMPTY;
        }
        if (prevRestrictions == null) {
            prevRestrictions = Bundle.EMPTY;
        }
    public static void applyUserRestrictionsLR(Context context, int userId,
            Bundle newRestrictions, Bundle prevRestrictions) {
        for (String key : USER_RESTRICTIONS) {
            final boolean newValue = newRestrictions.getBoolean(key);
            final boolean prevValue = prevRestrictions.getBoolean(key);

            if (newValue != prevValue) {
                applyUserRestriction(context, userId, key, newValue);
                applyUserRestrictionLR(context, userId, key, newValue);
            }
        }
    }

    private static void applyUserRestriction(Context context, int userId, String key,
    /**
     * Apply each user restriction.
     *
     * <p>Note this method is called by {@link UserManagerService} while holding
     * {@code mRestrictionLock}. Be aware when calling into other services, which could cause
     * a deadlock.
     */
    private static void applyUserRestrictionLR(Context context, int userId, String key,
            boolean newValue) {
        // When certain restrictions are cleared, we don't update the system settings,
        // because these settings are changeable on the Settings UI and we don't know the original
@@ -161,14 +166,6 @@ public class UserRestrictionsUtils {
        final long id = Binder.clearCallingIdentity();
        try {
            switch (key) {
                case UserManager.DISALLOW_UNMUTE_MICROPHONE:
                    IAudioService.Stub.asInterface(ServiceManager.getService(Context.AUDIO_SERVICE))
                            .setMicrophoneMute(newValue, context.getPackageName(), userId);
                    break;
                case UserManager.DISALLOW_ADJUST_VOLUME:
                    IAudioService.Stub.asInterface(ServiceManager.getService(Context.AUDIO_SERVICE))
                            .setMasterMute(newValue, 0, context.getPackageName(), userId);
                    break;
                case UserManager.DISALLOW_CONFIG_WIFI:
                    if (newValue) {
                        android.provider.Settings.Secure.putIntForUser(cr,
@@ -231,8 +228,6 @@ public class UserRestrictionsUtils {
                    }
                    break;
            }
        } catch (RemoteException re) {
            Slog.e(TAG, "Failed to talk to AudioService.", re);
        } finally {
            Binder.restoreCallingIdentity(id);
        }
+0 −4
Original line number Diff line number Diff line
@@ -212,8 +212,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
        DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_CONFIG_CELL_BROADCASTS);
        DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS);
        DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA);
        DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_UNMUTE_MICROPHONE);
        DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_ADJUST_VOLUME);
        DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_SMS);
        DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_FUN);
        DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_SAFE_BOOT);
@@ -4648,7 +4646,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
            mIPackageManager.updatePermissionFlagsForAllApps(
                    PackageManager.FLAG_PERMISSION_POLICY_FIXED,
                    0  /* flagValues */, userHandle.getIdentifier());
            // TODO This will not revert audio mute restrictions if they were set.  b/24981972
            synchronized (mUserManagerInternal.getUserRestrictionsLock()) {
                mUserManagerInternal.updateEffectiveUserRestrictionsLR(userHandle.getIdentifier());
            }
@@ -5607,7 +5604,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
    public void setUserRestriction(ComponentName who, String key, boolean enabledFromThisOwner) {
        Preconditions.checkNotNull(who, "ComponentName is null");
        final int userHandle = mInjector.userHandleGetCallingUserId();
        final UserHandle user = new UserHandle(userHandle);
        synchronized (mUserManagerInternal.getUserRestrictionsLock()) {
            synchronized (this) {
                ActiveAdmin activeAdmin =