summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Nate Myren <ntmyren@google.com> 2020-09-15 14:25:14 -0700
committer Nate Myren <ntmyren@google.com> 2020-09-16 13:35:00 -0700
commitf20a6afcc3a1578b6cc92237c4f85cfc11c39ee2 (patch)
tree2d99bfe0a81a1ebdcf88077c26f6b4cc0542499c
parent969e1943257c36c0678f70edfa47d05e1182d96a (diff)
Observe mic mute changes, consider recordingss paused when muted
Listen for the microphone mute state to change, and when it changes, update the paused status of all audio recordings. If the mic is muted, then every stream is considered paused. Fixes: 168553482 Test: Get a call, then screen it. The "mic in use" icon should be replaced by the mute icon Change-Id: I5fad1f359c7009c924e8f7cce9c09f8ea299522a
-rw-r--r--packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java27
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java8
2 files changed, 32 insertions, 3 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java
index a3339f6fc051..0fd47654ebb9 100644
--- a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java
@@ -16,8 +16,13 @@
package com.android.systemui.appops;
+import static android.media.AudioManager.ACTION_MICROPHONE_MUTE_CHANGED;
+
import android.app.AppOpsManager;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.location.LocationManager;
import android.media.AudioManager;
@@ -34,6 +39,7 @@ import androidx.annotation.WorkerThread;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.Dumpable;
+import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dump.DumpManager;
@@ -54,7 +60,7 @@ import javax.inject.Inject;
* NotificationPresenter to be displayed to the user.
*/
@SysUISingleton
-public class AppOpsControllerImpl implements AppOpsController,
+public class AppOpsControllerImpl extends BroadcastReceiver implements AppOpsController,
AppOpsManager.OnOpActiveChangedInternalListener,
AppOpsManager.OnOpNotedListener, Dumpable {
@@ -65,6 +71,7 @@ public class AppOpsControllerImpl implements AppOpsController,
private static final String TAG = "AppOpsControllerImpl";
private static final boolean DEBUG = false;
+ private final BroadcastDispatcher mDispatcher;
private final AppOpsManager mAppOps;
private final AudioManager mAudioManager;
private final LocationManager mLocationManager;
@@ -79,6 +86,7 @@ public class AppOpsControllerImpl implements AppOpsController,
private final SparseArray<Set<Callback>> mCallbacksByCode = new SparseArray<>();
private final PermissionFlagsCache mFlagsCache;
private boolean mListening;
+ private boolean mMicMuted;
@GuardedBy("mActiveItems")
private final List<AppOpItem> mActiveItems = new ArrayList<>();
@@ -105,8 +113,10 @@ public class AppOpsControllerImpl implements AppOpsController,
@Background Looper bgLooper,
DumpManager dumpManager,
PermissionFlagsCache cache,
- AudioManager audioManager
+ AudioManager audioManager,
+ BroadcastDispatcher dispatcher
) {
+ mDispatcher = dispatcher;
mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
mFlagsCache = cache;
mBGHandler = new H(bgLooper);
@@ -115,6 +125,7 @@ public class AppOpsControllerImpl implements AppOpsController,
mCallbacksByCode.put(OPS[i], new ArraySet<>());
}
mAudioManager = audioManager;
+ mMicMuted = audioManager.isMicrophoneMute();
mLocationManager = context.getSystemService(LocationManager.class);
dumpManager.registerDumpable(TAG, this);
}
@@ -133,6 +144,8 @@ public class AppOpsControllerImpl implements AppOpsController,
mAudioManager.registerAudioRecordingCallback(mAudioRecordingCallback, mBGHandler);
mBGHandler.post(() -> mAudioRecordingCallback.onRecordingConfigChanged(
mAudioManager.getActiveRecordingConfigurations()));
+ mDispatcher.registerReceiverWithHandler(this,
+ new IntentFilter(ACTION_MICROPHONE_MUTE_CHANGED), mBGHandler);
} else {
mAppOps.stopWatchingActive(this);
@@ -140,6 +153,7 @@ public class AppOpsControllerImpl implements AppOpsController,
mAudioManager.unregisterAudioRecordingCallback(mAudioRecordingCallback);
mBGHandler.removeCallbacksAndMessages(null); // null removes all
+ mDispatcher.unregisterReceiver(this);
synchronized (mActiveItems) {
mActiveItems.clear();
mRecordingsByUid.clear();
@@ -468,6 +482,9 @@ public class AppOpsControllerImpl implements AppOpsController,
}
private boolean isAnyRecordingPausedLocked(int uid) {
+ if (mMicMuted) {
+ return true;
+ }
List<AudioRecordingConfiguration> configs = mRecordingsByUid.get(uid);
if (configs == null) return false;
int configsNum = configs.size();
@@ -522,6 +539,12 @@ public class AppOpsControllerImpl implements AppOpsController,
}
};
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ mMicMuted = mAudioManager.isMicrophoneMute();
+ updateRecordingPausedStatus();
+ }
+
protected class H extends Handler {
H(Looper looper) {
super(looper);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java
index 8f082c15df36..ade329011b7d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java
@@ -47,6 +47,7 @@ import android.testing.TestableLooper;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dump.DumpManager;
import org.junit.Before;
@@ -82,6 +83,8 @@ public class AppOpsControllerTest extends SysuiTestCase {
private PackageManager mPackageManager;
@Mock(stubOnly = true)
private AudioManager mAudioManager;
+ @Mock()
+ private BroadcastDispatcher mDispatcher;
@Mock(stubOnly = true)
private AudioManager.AudioRecordingCallback mRecordingCallback;
@Mock(stubOnly = true)
@@ -120,7 +123,8 @@ public class AppOpsControllerTest extends SysuiTestCase {
mTestableLooper.getLooper(),
mDumpManager,
mFlagsCache,
- mAudioManager
+ mAudioManager,
+ mDispatcher
);
}
@@ -128,12 +132,14 @@ public class AppOpsControllerTest extends SysuiTestCase {
public void testOnlyListenForFewOps() {
mController.setListening(true);
verify(mAppOpsManager, times(1)).startWatchingActive(AppOpsControllerImpl.OPS, mController);
+ verify(mDispatcher, times(1)).registerReceiverWithHandler(eq(mController), any(), any());
}
@Test
public void testStopListening() {
mController.setListening(false);
verify(mAppOpsManager, times(1)).stopWatchingActive(mController);
+ verify(mDispatcher, times(1)).unregisterReceiver(mController);
}
@Test