Loading core/res/AndroidManifest.xml +4 −0 Original line number Diff line number Diff line Loading @@ -2316,6 +2316,10 @@ <permission android:name="android.permission.MODIFY_ACCESSIBILITY_DATA" android:protectionLevel="signature" /> <!-- @hide Allows an application to change the accessibility volume. --> <permission android:name="android.permission.CHANGE_ACCESSIBILITY_VOLUME" android:protectionLevel="signature" /> <!-- @hide Allows an application to collect frame statistics --> <permission android:name="android.permission.FRAME_STATS" android:protectionLevel="signature" /> Loading media/java/android/media/AudioManagerInternal.java +3 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ */ package android.media; import android.util.IntArray; import com.android.server.LocalServices; /** Loading Loading @@ -43,6 +44,8 @@ public abstract class AudioManagerInternal { public abstract void updateRingerModeAffectedStreamsInternal(); public abstract void setAccessibilityServiceUids(IntArray uids); public interface RingerModeDelegate { /** Called when external ringer mode is evaluated, returns the new internal ringer mode */ int onSetRingerModeExternal(int ringerModeOld, int ringerModeNew, String caller, Loading packages/SystemUI/AndroidManifest.xml +1 −1 Original line number Diff line number Diff line Loading @@ -181,7 +181,7 @@ <uses-permission android:name="android.permission.MODIFY_ACCESSIBILITY_DATA" /> <!-- to control accessibility volume --> <uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE" /> <uses-permission android:name="android.permission.CHANGE_ACCESSIBILITY_VOLUME" /> <application android:name=".SystemUIApplication" Loading services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +19 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ import android.graphics.Region; import android.hardware.display.DisplayManager; import android.hardware.fingerprint.IFingerprintService; import android.hardware.input.InputManager; import android.media.AudioManagerInternal; import android.net.Uri; import android.os.Binder; import android.os.Build; Loading @@ -75,6 +76,7 @@ import android.provider.SettingsStringUtil.ComponentNameSet; import android.provider.SettingsStringUtil.SettingStringHelper; import android.text.TextUtils; import android.text.TextUtils.SimpleStringSplitter; import android.util.IntArray; import android.util.Slog; import android.util.SparseArray; import android.view.Display; Loading Loading @@ -220,6 +222,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { private final List<AccessibilityServiceInfo> mTempAccessibilityServiceInfoList = new ArrayList<>(); private final IntArray mTempIntArray = new IntArray(0); private final RemoteCallbackList<IAccessibilityManagerClient> mGlobalClients = new RemoteCallbackList<>(); Loading Loading @@ -1558,6 +1562,21 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { } } final int count = userState.mBoundServices.size(); mTempIntArray.clear(); for (int i = 0; i < count; i++) { final ResolveInfo resolveInfo = userState.mBoundServices.get(i).mAccessibilityServiceInfo.getResolveInfo(); if (resolveInfo != null) { mTempIntArray.add(resolveInfo.serviceInfo.applicationInfo.uid); } } // Calling out with lock held, but to a lower-level service final AudioManagerInternal audioManager = LocalServices.getService(AudioManagerInternal.class); if (audioManager != null) { audioManager.setAccessibilityServiceUids(mTempIntArray); } updateAccessibilityEnabledSetting(userState); } Loading services/core/java/com/android/server/audio/AudioService.java +51 −8 Original line number Diff line number Diff line Loading @@ -106,6 +106,7 @@ import android.text.TextUtils; import android.util.AndroidRuntimeException; import android.util.ArrayMap; import android.util.ArraySet; import android.util.IntArray; import android.util.Log; import android.util.MathUtils; import android.util.Slog; Loading @@ -126,6 +127,7 @@ import java.io.IOException; import java.io.PrintWriter; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; Loading Loading @@ -575,6 +577,10 @@ public class AudioService extends IAudioService.Stub private VolumePolicy mVolumePolicy = VolumePolicy.DEFAULT; private long mLoweredFromNormalToVibrateTime; // Array of Uids of valid accessibility services to check if caller is one of them private int[] mAccessibilityServiceUids; private final Object mAccessibilityServiceUidsLock = new Object(); // Intent "extra" data keys. public static final String CONNECT_INTENT_KEY_PORT_NAME = "portName"; public static final String CONNECT_INTENT_KEY_STATE = "state"; Loading Loading @@ -1241,11 +1247,9 @@ public class AudioService extends IAudioService.Stub /** @see AudioManager#adjustStreamVolume(int, int, int) */ public void adjustStreamVolume(int streamType, int direction, int flags, String callingPackage) { if ( streamType == AudioManager.STREAM_ACCESSIBILITY && (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission( android.Manifest.permission.BIND_ACCESSIBILITY_SERVICE))) { if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) { Log.w(TAG, "Trying to call adjustStreamVolume() for a11y without" + "BIND_ACCESSIBILITY_SERVICE / callingPackage=" + callingPackage); + "CHANGE_ACCESSIBILITY_VOLUME / callingPackage=" + callingPackage); return; } adjustStreamVolume(streamType, direction, flags, callingPackage, callingPackage, Loading Loading @@ -1559,17 +1563,33 @@ public class AudioService extends IAudioService.Stub /** @see AudioManager#setStreamVolume(int, int, int) */ public void setStreamVolume(int streamType, int index, int flags, String callingPackage) { if ( streamType == AudioManager.STREAM_ACCESSIBILITY && (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission( android.Manifest.permission.BIND_ACCESSIBILITY_SERVICE))) { if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) { Log.w(TAG, "Trying to call setStreamVolume() for a11y without" + " BIND_ACCESSIBILITY_SERVICE callingPackage=" + callingPackage); + " CHANGE_ACCESSIBILITY_VOLUME callingPackage=" + callingPackage); return; } setStreamVolume(streamType, index, flags, callingPackage, callingPackage, Binder.getCallingUid()); } private boolean canChangeAccessibilityVolume() { synchronized (mAccessibilityServiceUidsLock) { if (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission( android.Manifest.permission.CHANGE_ACCESSIBILITY_VOLUME)) { return true; } if (mAccessibilityServiceUids != null) { int callingUid = Binder.getCallingUid(); for (int i = 0; i < mAccessibilityServiceUids.length; i++) { if (mAccessibilityServiceUids[i] == callingUid) { return true; } } } return false; } } private void setStreamVolume(int streamType, int index, int flags, String callingPackage, String caller, int uid) { if (DEBUG_VOL) { Loading Loading @@ -6380,6 +6400,29 @@ public class AudioService extends IAudioService.Stub } } } @Override public void setAccessibilityServiceUids(IntArray uids) { synchronized (mAccessibilityServiceUidsLock) { if (uids.size() == 0) { mAccessibilityServiceUids = null; } else { boolean changed = (mAccessibilityServiceUids == null) || (mAccessibilityServiceUids.length != uids.size()); if (!changed) { for (int i = 0; i < mAccessibilityServiceUids.length; i++) { if (uids.get(i) != mAccessibilityServiceUids[i]) { changed = true; break; } } } if (changed) { mAccessibilityServiceUids = uids.toArray(); } } } } } //========================================================================================== Loading Loading
core/res/AndroidManifest.xml +4 −0 Original line number Diff line number Diff line Loading @@ -2316,6 +2316,10 @@ <permission android:name="android.permission.MODIFY_ACCESSIBILITY_DATA" android:protectionLevel="signature" /> <!-- @hide Allows an application to change the accessibility volume. --> <permission android:name="android.permission.CHANGE_ACCESSIBILITY_VOLUME" android:protectionLevel="signature" /> <!-- @hide Allows an application to collect frame statistics --> <permission android:name="android.permission.FRAME_STATS" android:protectionLevel="signature" /> Loading
media/java/android/media/AudioManagerInternal.java +3 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ */ package android.media; import android.util.IntArray; import com.android.server.LocalServices; /** Loading Loading @@ -43,6 +44,8 @@ public abstract class AudioManagerInternal { public abstract void updateRingerModeAffectedStreamsInternal(); public abstract void setAccessibilityServiceUids(IntArray uids); public interface RingerModeDelegate { /** Called when external ringer mode is evaluated, returns the new internal ringer mode */ int onSetRingerModeExternal(int ringerModeOld, int ringerModeNew, String caller, Loading
packages/SystemUI/AndroidManifest.xml +1 −1 Original line number Diff line number Diff line Loading @@ -181,7 +181,7 @@ <uses-permission android:name="android.permission.MODIFY_ACCESSIBILITY_DATA" /> <!-- to control accessibility volume --> <uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE" /> <uses-permission android:name="android.permission.CHANGE_ACCESSIBILITY_VOLUME" /> <application android:name=".SystemUIApplication" Loading
services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +19 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ import android.graphics.Region; import android.hardware.display.DisplayManager; import android.hardware.fingerprint.IFingerprintService; import android.hardware.input.InputManager; import android.media.AudioManagerInternal; import android.net.Uri; import android.os.Binder; import android.os.Build; Loading @@ -75,6 +76,7 @@ import android.provider.SettingsStringUtil.ComponentNameSet; import android.provider.SettingsStringUtil.SettingStringHelper; import android.text.TextUtils; import android.text.TextUtils.SimpleStringSplitter; import android.util.IntArray; import android.util.Slog; import android.util.SparseArray; import android.view.Display; Loading Loading @@ -220,6 +222,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { private final List<AccessibilityServiceInfo> mTempAccessibilityServiceInfoList = new ArrayList<>(); private final IntArray mTempIntArray = new IntArray(0); private final RemoteCallbackList<IAccessibilityManagerClient> mGlobalClients = new RemoteCallbackList<>(); Loading Loading @@ -1558,6 +1562,21 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { } } final int count = userState.mBoundServices.size(); mTempIntArray.clear(); for (int i = 0; i < count; i++) { final ResolveInfo resolveInfo = userState.mBoundServices.get(i).mAccessibilityServiceInfo.getResolveInfo(); if (resolveInfo != null) { mTempIntArray.add(resolveInfo.serviceInfo.applicationInfo.uid); } } // Calling out with lock held, but to a lower-level service final AudioManagerInternal audioManager = LocalServices.getService(AudioManagerInternal.class); if (audioManager != null) { audioManager.setAccessibilityServiceUids(mTempIntArray); } updateAccessibilityEnabledSetting(userState); } Loading
services/core/java/com/android/server/audio/AudioService.java +51 −8 Original line number Diff line number Diff line Loading @@ -106,6 +106,7 @@ import android.text.TextUtils; import android.util.AndroidRuntimeException; import android.util.ArrayMap; import android.util.ArraySet; import android.util.IntArray; import android.util.Log; import android.util.MathUtils; import android.util.Slog; Loading @@ -126,6 +127,7 @@ import java.io.IOException; import java.io.PrintWriter; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; Loading Loading @@ -575,6 +577,10 @@ public class AudioService extends IAudioService.Stub private VolumePolicy mVolumePolicy = VolumePolicy.DEFAULT; private long mLoweredFromNormalToVibrateTime; // Array of Uids of valid accessibility services to check if caller is one of them private int[] mAccessibilityServiceUids; private final Object mAccessibilityServiceUidsLock = new Object(); // Intent "extra" data keys. public static final String CONNECT_INTENT_KEY_PORT_NAME = "portName"; public static final String CONNECT_INTENT_KEY_STATE = "state"; Loading Loading @@ -1241,11 +1247,9 @@ public class AudioService extends IAudioService.Stub /** @see AudioManager#adjustStreamVolume(int, int, int) */ public void adjustStreamVolume(int streamType, int direction, int flags, String callingPackage) { if ( streamType == AudioManager.STREAM_ACCESSIBILITY && (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission( android.Manifest.permission.BIND_ACCESSIBILITY_SERVICE))) { if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) { Log.w(TAG, "Trying to call adjustStreamVolume() for a11y without" + "BIND_ACCESSIBILITY_SERVICE / callingPackage=" + callingPackage); + "CHANGE_ACCESSIBILITY_VOLUME / callingPackage=" + callingPackage); return; } adjustStreamVolume(streamType, direction, flags, callingPackage, callingPackage, Loading Loading @@ -1559,17 +1563,33 @@ public class AudioService extends IAudioService.Stub /** @see AudioManager#setStreamVolume(int, int, int) */ public void setStreamVolume(int streamType, int index, int flags, String callingPackage) { if ( streamType == AudioManager.STREAM_ACCESSIBILITY && (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission( android.Manifest.permission.BIND_ACCESSIBILITY_SERVICE))) { if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) { Log.w(TAG, "Trying to call setStreamVolume() for a11y without" + " BIND_ACCESSIBILITY_SERVICE callingPackage=" + callingPackage); + " CHANGE_ACCESSIBILITY_VOLUME callingPackage=" + callingPackage); return; } setStreamVolume(streamType, index, flags, callingPackage, callingPackage, Binder.getCallingUid()); } private boolean canChangeAccessibilityVolume() { synchronized (mAccessibilityServiceUidsLock) { if (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission( android.Manifest.permission.CHANGE_ACCESSIBILITY_VOLUME)) { return true; } if (mAccessibilityServiceUids != null) { int callingUid = Binder.getCallingUid(); for (int i = 0; i < mAccessibilityServiceUids.length; i++) { if (mAccessibilityServiceUids[i] == callingUid) { return true; } } } return false; } } private void setStreamVolume(int streamType, int index, int flags, String callingPackage, String caller, int uid) { if (DEBUG_VOL) { Loading Loading @@ -6380,6 +6400,29 @@ public class AudioService extends IAudioService.Stub } } } @Override public void setAccessibilityServiceUids(IntArray uids) { synchronized (mAccessibilityServiceUidsLock) { if (uids.size() == 0) { mAccessibilityServiceUids = null; } else { boolean changed = (mAccessibilityServiceUids == null) || (mAccessibilityServiceUids.length != uids.size()); if (!changed) { for (int i = 0; i < mAccessibilityServiceUids.length; i++) { if (uids.get(i) != mAccessibilityServiceUids[i]) { changed = true; break; } } } if (changed) { mAccessibilityServiceUids = uids.toArray(); } } } } } //========================================================================================== Loading