Do not show recent mic usage if the recording is silenced
Test: Recorded audio in background and could not open review-ongoing
usage dialog1
Bug: 162547999
Change-Id: Ica9eb877d2122d785ed16e7581325082efbdc1f7
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 30d6f6e..54b7436 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -46,6 +46,7 @@
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.GET_ACCOUNTS_PRIVILEGED" />
+ <uses-permission android:name="android.permission.MODIFY_AUDIO_ROUTING" />
<uses-sdk android:minSdkVersion="29" android:targetSdkVersion="29" />
diff --git a/src/com/android/permissioncontroller/permission/debug/AppPermissionUsage.java b/src/com/android/permissioncontroller/permission/debug/AppPermissionUsage.java
index 5136d9b..7d75641 100644
--- a/src/com/android/permissioncontroller/permission/debug/AppPermissionUsage.java
+++ b/src/com/android/permissioncontroller/permission/debug/AppPermissionUsage.java
@@ -16,11 +16,14 @@
package com.android.permissioncontroller.permission.debug;
+import static android.Manifest.permission_group.MICROPHONE;
+
import android.app.AppOpsManager;
import android.app.AppOpsManager.HistoricalOp;
import android.app.AppOpsManager.HistoricalPackageOps;
import android.app.AppOpsManager.OpEntry;
import android.app.AppOpsManager.PackageOps;
+import android.media.AudioRecordingConfiguration;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -43,11 +46,35 @@
private AppPermissionUsage(@NonNull PermissionApp permissionApp,
@NonNull List<AppPermissionGroup> groups, @Nullable PackageOps lastUsage,
- @Nullable HistoricalPackageOps historicalUsage) {
+ @Nullable HistoricalPackageOps historicalUsage,
+ @Nullable ArrayList<AudioRecordingConfiguration> recordings) {
mPermissionApp = permissionApp;
final int groupCount = groups.size();
for (int i = 0; i < groupCount; i++) {
final AppPermissionGroup group = groups.get(i);
+
+ /**
+ * TODO: HACK HACK HACK.
+ *
+ * Exclude for the UIDs that are currently silenced. This happens if an app keeps
+ * recording while in the background for more than a few seconds.
+ */
+ if (recordings != null && group.getName().equals(MICROPHONE)) {
+ boolean isSilenced = false;
+ int recordingsCount = recordings.size();
+ for (int recordingNum = 0; recordingNum < recordingsCount; recordingNum++) {
+ AudioRecordingConfiguration recording = recordings.get(recordingNum);
+ if (recording.isClientSilenced()) {
+ isSilenced = true;
+ break;
+ }
+ }
+
+ if (isSilenced) {
+ continue;
+ }
+ }
+
mGroupUsages.add(new GroupUsage(group, lastUsage, historicalUsage));
}
}
@@ -238,6 +265,7 @@
private final @NonNull PermissionApp mPermissionApp;
private @Nullable PackageOps mLastUsage;
private @Nullable HistoricalPackageOps mHistoricalUsage;
+ private @Nullable ArrayList<AudioRecordingConfiguration> mAudioRecordingConfigurations;
public Builder(@NonNull PermissionApp permissionApp) {
mPermissionApp = permissionApp;
@@ -258,11 +286,18 @@
return this;
}
+ public @NonNull Builder setRecordingConfiguration(
+ @Nullable ArrayList<AudioRecordingConfiguration> recordings) {
+ mAudioRecordingConfigurations = recordings;
+ return this;
+ }
+
public @NonNull AppPermissionUsage build() {
if (mGroups.isEmpty()) {
throw new IllegalStateException("mGroups cannot be empty.");
}
- return new AppPermissionUsage(mPermissionApp, mGroups, mLastUsage, mHistoricalUsage);
+ return new AppPermissionUsage(mPermissionApp, mGroups, mLastUsage, mHistoricalUsage,
+ mAudioRecordingConfigurations);
}
}
}
diff --git a/src/com/android/permissioncontroller/permission/debug/PermissionUsages.java b/src/com/android/permissioncontroller/permission/debug/PermissionUsages.java
index db25d74..dfba512 100644
--- a/src/com/android/permissioncontroller/permission/debug/PermissionUsages.java
+++ b/src/com/android/permissioncontroller/permission/debug/PermissionUsages.java
@@ -27,11 +27,14 @@
import android.content.AsyncTaskLoader;
import android.content.Context;
import android.content.Loader;
+import android.media.AudioManager;
+import android.media.AudioRecordingConfiguration;
import android.os.Bundle;
import android.os.Process;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Pair;
+import android.util.SparseArray;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -320,6 +323,25 @@
}
}
+ // Get audio recording config
+ List<AudioRecordingConfiguration> allRecordings = getContext()
+ .getSystemService(AudioManager.class).getActiveRecordingConfigurations();
+ SparseArray<ArrayList<AudioRecordingConfiguration>> recordingsByUid =
+ new SparseArray<>();
+
+ final int recordingsCount = allRecordings.size();
+ for (int i = 0; i < recordingsCount; i++) {
+ AudioRecordingConfiguration recording = allRecordings.get(i);
+
+ ArrayList<AudioRecordingConfiguration> recordings = recordingsByUid.get(
+ recording.getClientUid());
+ if (recordings == null) {
+ recordings = new ArrayList<>();
+ recordingsByUid.put(recording.getClientUid(), recordings);
+ }
+ recordings.add(recording);
+ }
+
// Construct the historical usages based on data we fetched
final int builderCount = usageBuilders.size();
for (int i = 0; i < builderCount; i++) {
@@ -329,6 +351,7 @@
usageBuilder.setLastUsage(lastUsage);
final HistoricalPackageOps historicalUsage = historicalUsages.get(key);
usageBuilder.setHistoricalUsage(historicalUsage);
+ usageBuilder.setRecordingConfiguration(recordingsByUid.get(key.first));
usages.add(usageBuilder.build());
}