Merge "Reuse phone privacy indicator impl. for tv" into sc-dev
diff --git a/packages/SystemUI/res/layout/tv_audio_recording_indicator.xml b/packages/SystemUI/res/layout/tv_audio_recording_indicator.xml
deleted file mode 100644
index b62018d..0000000
--- a/packages/SystemUI/res/layout/tv_audio_recording_indicator.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2019 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:layout_width="wrap_content"
-              android:layout_height="wrap_content"
-              android:orientation="horizontal"
-              android:padding="12dp">
-
-    <FrameLayout
-        android:layout_width="34dp"
-        android:layout_height="24dp"
-        android:layout_gravity="center"
-        android:background="@drawable/tv_rect_shadow_rounded">
-
-        <ImageView
-            android:layout_width="13dp"
-            android:layout_height="13dp"
-            android:layout_gravity="center"
-            android:src="@drawable/tv_ic_mic_white"/>
-
-    </FrameLayout>
-
-</LinearLayout>
diff --git a/packages/SystemUI/res/layout/tv_ongoing_privacy_chip.xml b/packages/SystemUI/res/layout/tv_ongoing_privacy_chip.xml
new file mode 100644
index 0000000..dff148b
--- /dev/null
+++ b/packages/SystemUI/res/layout/tv_ongoing_privacy_chip.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2019 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:padding="12dp"
+    android:layout_gravity="center">
+
+    <LinearLayout
+        android:id="@+id/icons_container"
+        android:background="@drawable/tv_rect_shadow_rounded"
+        android:padding="@dimen/privacy_chip_icon_padding"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:orientation="horizontal"/>
+
+</FrameLayout>
+
diff --git a/packages/SystemUI/res/values-television/config.xml b/packages/SystemUI/res/values-television/config.xml
index 722f148..b02d8b8 100644
--- a/packages/SystemUI/res/values-television/config.xml
+++ b/packages/SystemUI/res/values-television/config.xml
@@ -28,6 +28,7 @@
     <string-array name="config_systemUIServiceComponents" translatable="false">
         <item>com.android.systemui.util.NotificationChannels</item>
         <item>com.android.systemui.volume.VolumeUI</item>
+        <item>com.android.systemui.privacy.television.TvOngoingPrivacyChip</item>
         <item>com.android.systemui.statusbar.tv.TvStatusBar</item>
         <item>com.android.systemui.statusbar.tv.notifications.TvNotificationPanel</item>
         <item>com.android.systemui.statusbar.tv.notifications.TvNotificationHandler</item>
diff --git a/packages/SystemUI/res/values-television/dimens.xml b/packages/SystemUI/res/values-television/dimens.xml
index 6da0c69..7626db9 100644
--- a/packages/SystemUI/res/values-television/dimens.xml
+++ b/packages/SystemUI/res/values-television/dimens.xml
@@ -17,4 +17,8 @@
 <resources>
     <!-- Opacity at which the background for the shutdown UI will be drawn. -->
     <item name="shutdown_scrim_behind_alpha" format="float" type="dimen">1.0</item>
+
+    <dimen name="privacy_chip_icon_margin">3dp</dimen>
+    <dimen name="privacy_chip_icon_padding">8dp</dimen>
+    <dimen name="privacy_chip_icon_size">13dp</dimen>
 </resources>
\ No newline at end of file
diff --git a/packages/SystemUI/res/values/config_tv.xml b/packages/SystemUI/res/values/config_tv.xml
deleted file mode 100644
index 2e77674..0000000
--- a/packages/SystemUI/res/values/config_tv.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<resources>
-    <!-- Whether to enable microphone disclosure indicator
-         (com.android.systemui.statusbar.tv.micdisclosure.AudioRecordingDisclosureBar). -->
-    <bool name="audio_recording_disclosure_enabled">true</bool>
-</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
index ec3188a..5d226d5 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
@@ -29,6 +29,7 @@
 import com.android.systemui.media.systemsounds.HomeSoundEffectController;
 import com.android.systemui.people.widget.PeopleSpaceWidgetEnabler;
 import com.android.systemui.power.PowerUI;
+import com.android.systemui.privacy.television.TvOngoingPrivacyChip;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.RecentsModule;
 import com.android.systemui.shortcut.ShortcutKeyDispatcher;
@@ -155,6 +156,12 @@
     @ClassKey(TvNotificationPanel.class)
     public abstract SystemUI bindsTvNotificationPanel(TvNotificationPanel sysui);
 
+    /** Inject into TvOngoingPrivacyChip. */
+    @Binds
+    @IntoMap
+    @ClassKey(TvOngoingPrivacyChip.class)
+    public abstract SystemUI bindsTvOngoingPrivacyChip(TvOngoingPrivacyChip sysui);
+
     /** Inject into VolumeUI. */
     @Binds
     @IntoMap
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/television/TvOngoingPrivacyChip.java b/packages/SystemUI/src/com/android/systemui/privacy/television/TvOngoingPrivacyChip.java
new file mode 100644
index 0000000..0fa7b59
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/privacy/television/TvOngoingPrivacyChip.java
@@ -0,0 +1,334 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.privacy.television;
+
+import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.annotation.IntDef;
+import android.annotation.UiThread;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Color;
+import android.graphics.PixelFormat;
+import android.graphics.drawable.Drawable;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+import android.view.WindowManager;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+
+import com.android.systemui.R;
+import com.android.systemui.SystemUI;
+import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.privacy.PrivacyChipBuilder;
+import com.android.systemui.privacy.PrivacyItem;
+import com.android.systemui.privacy.PrivacyItemController;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.List;
+
+import javax.inject.Inject;
+
+/**
+ * A SystemUI component responsible for notifying the user whenever an application is
+ * recording audio, accessing the camera or accessing the location.
+ */
+@SysUISingleton
+public class TvOngoingPrivacyChip extends SystemUI implements PrivacyItemController.Callback {
+    private static final String TAG = "TvOngoingPrivacyChip";
+    static final boolean DEBUG = false;
+
+    // This title is used in CameraMicIndicatorsPermissionTest and
+    // RecognitionServiceMicIndicatorTest.
+    private static final String LAYOUT_PARAMS_TITLE = "MicrophoneCaptureIndicator";
+
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = {"STATE_"}, value = {
+            STATE_NOT_SHOWN,
+            STATE_APPEARING,
+            STATE_SHOWN,
+            STATE_DISAPPEARING
+    })
+    public @interface State {
+    }
+
+    private static final int STATE_NOT_SHOWN = 0;
+    private static final int STATE_APPEARING = 1;
+    private static final int STATE_SHOWN = 2;
+    private static final int STATE_DISAPPEARING = 3;
+
+    private static final int ANIMATION_DURATION_MS = 200;
+
+    private final Context mContext;
+    private final PrivacyItemController mPrivacyItemController;
+
+    private View mIndicatorView;
+    private boolean mViewAndWindowAdded;
+    private ObjectAnimator mAnimator;
+
+    private boolean mAllIndicatorsFlagEnabled;
+    private boolean mMicCameraIndicatorFlagEnabled;
+    private boolean mLocationIndicatorEnabled;
+    private List<PrivacyItem> mPrivacyItems;
+
+    private LinearLayout mIconsContainer;
+    private final int mIconSize;
+    private final int mIconMarginStart;
+
+    @State
+    private int mState = STATE_NOT_SHOWN;
+
+    @Inject
+    public TvOngoingPrivacyChip(Context context, PrivacyItemController privacyItemController) {
+        super(context);
+        Log.d(TAG, "Privacy chip running without id");
+        mContext = context;
+        mPrivacyItemController = privacyItemController;
+
+        Resources res = mContext.getResources();
+        mIconMarginStart = Math.round(res.getDimension(R.dimen.privacy_chip_icon_margin));
+        mIconSize = res.getDimensionPixelSize(R.dimen.privacy_chip_icon_size);
+
+        mAllIndicatorsFlagEnabled = privacyItemController.getAllIndicatorsAvailable();
+        mMicCameraIndicatorFlagEnabled = privacyItemController.getMicCameraAvailable();
+        mLocationIndicatorEnabled = privacyItemController.getLocationAvailable();
+
+        if (DEBUG) {
+            Log.d(TAG, "allIndicators: " + mAllIndicatorsFlagEnabled);
+            Log.d(TAG, "micCameraIndicators: " + mMicCameraIndicatorFlagEnabled);
+            Log.d(TAG, "locationIndicators: " + mLocationIndicatorEnabled);
+        }
+    }
+
+    @Override
+    public void start() {
+        mPrivacyItemController.addCallback(this);
+    }
+
+    @Override
+    public void onPrivacyItemsChanged(List<PrivacyItem> privacyItems) {
+        if (DEBUG) Log.d(TAG, "PrivacyItemsChanged");
+        mPrivacyItems = privacyItems;
+        updateUI();
+    }
+
+    @Override
+    public void onFlagAllChanged(boolean flag) {
+        if (DEBUG) Log.d(TAG, "all indicators enabled: " + flag);
+        mAllIndicatorsFlagEnabled = flag;
+    }
+
+    @Override
+    public void onFlagMicCameraChanged(boolean flag) {
+        if (DEBUG) Log.d(TAG, "mic/camera indicators enabled: " + flag);
+        mMicCameraIndicatorFlagEnabled = flag;
+    }
+
+    @Override
+    public void onFlagLocationChanged(boolean flag) {
+        if (DEBUG) Log.d(TAG, "location indicators enabled: " + flag);
+        mLocationIndicatorEnabled = flag;
+    }
+
+    private void updateUI() {
+        if (DEBUG) Log.d(TAG, mPrivacyItems.size() + " privacy items");
+
+        if ((mMicCameraIndicatorFlagEnabled || mAllIndicatorsFlagEnabled
+                || mLocationIndicatorEnabled) && !mPrivacyItems.isEmpty()) {
+            if (mState == STATE_NOT_SHOWN || mState == STATE_DISAPPEARING) {
+                showIndicator();
+            } else {
+                if (DEBUG) Log.d(TAG, "only updating icons");
+                PrivacyChipBuilder builder = new PrivacyChipBuilder(mContext, mPrivacyItems);
+                setIcons(builder.generateIcons(), mIconsContainer);
+                mIconsContainer.requestLayout();
+            }
+        } else {
+            hideIndicatorIfNeeded();
+        }
+    }
+
+    @UiThread
+    private void hideIndicatorIfNeeded() {
+        if (mState == STATE_NOT_SHOWN || mState == STATE_DISAPPEARING) return;
+
+        if (mViewAndWindowAdded) {
+            mState = STATE_DISAPPEARING;
+            animateDisappearance();
+        } else {
+            // Appearing animation has not started yet, as we were still waiting for the View to be
+            // laid out.
+            mState = STATE_NOT_SHOWN;
+            removeIndicatorView();
+        }
+    }
+
+    @UiThread
+    private void showIndicator() {
+        mState = STATE_APPEARING;
+
+        // Inflate the indicator view
+        mIndicatorView = LayoutInflater.from(mContext).inflate(
+                R.layout.tv_ongoing_privacy_chip, null);
+
+        // 1. Set alpha to 0.
+        // 2. Wait until the window is shown and the view is laid out.
+        // 3. Start a "fade in" (alpha) animation.
+        mIndicatorView.setAlpha(0f);
+        mIndicatorView
+                .getViewTreeObserver()
+                .addOnGlobalLayoutListener(
+                        new ViewTreeObserver.OnGlobalLayoutListener() {
+                            @Override
+                            public void onGlobalLayout() {
+                                // State could have changed to NOT_SHOWN (if all the recorders are
+                                // already gone)
+                                if (mState != STATE_APPEARING) return;
+
+                                mViewAndWindowAdded = true;
+                                // Remove the observer
+                                mIndicatorView.getViewTreeObserver().removeOnGlobalLayoutListener(
+                                        this);
+
+                                animateAppearance();
+                            }
+                        });
+
+        mIconsContainer = mIndicatorView.findViewById(R.id.icons_container);
+        PrivacyChipBuilder builder = new PrivacyChipBuilder(mContext, mPrivacyItems);
+        setIcons(builder.generateIcons(), mIconsContainer);
+
+        final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
+                WRAP_CONTENT,
+                WRAP_CONTENT,
+                WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
+                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
+                PixelFormat.TRANSLUCENT);
+        layoutParams.gravity = Gravity.TOP | Gravity.END;
+        layoutParams.setTitle(LAYOUT_PARAMS_TITLE);
+        layoutParams.packageName = mContext.getPackageName();
+        final WindowManager windowManager = mContext.getSystemService(WindowManager.class);
+        windowManager.addView(mIndicatorView, layoutParams);
+
+    }
+
+    private void setIcons(List<Drawable> icons, ViewGroup iconsContainer) {
+        iconsContainer.removeAllViews();
+        for (int i = 0; i < icons.size(); i++) {
+            Drawable icon = icons.get(i);
+            icon.mutate().setTint(Color.WHITE);
+            ImageView imageView = new ImageView(mContext);
+            imageView.setImageDrawable(icon);
+            imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
+            mIconsContainer.addView(imageView, mIconSize, mIconSize);
+            if (i != 0) {
+                ViewGroup.MarginLayoutParams layoutParams =
+                        (ViewGroup.MarginLayoutParams) imageView.getLayoutParams();
+                layoutParams.setMarginStart(mIconMarginStart);
+                imageView.setLayoutParams(layoutParams);
+            }
+        }
+    }
+
+    private void animateAppearance() {
+        animateAlphaTo(1f);
+    }
+
+    private void animateDisappearance() {
+        animateAlphaTo(0f);
+    }
+
+    private void animateAlphaTo(final float endValue) {
+        if (mAnimator == null) {
+            if (DEBUG) Log.d(TAG, "set up animator");
+
+            mAnimator = new ObjectAnimator();
+            mAnimator.setTarget(mIndicatorView);
+            mAnimator.setProperty(View.ALPHA);
+            mAnimator.addListener(new AnimatorListenerAdapter() {
+                boolean mCancelled;
+
+                @Override
+                public void onAnimationStart(Animator animation, boolean isReverse) {
+                    if (DEBUG) Log.d(TAG, "AnimatorListenerAdapter#onAnimationStart");
+                    mCancelled = false;
+                }
+
+                @Override
+                public void onAnimationCancel(Animator animation) {
+                    if (DEBUG) Log.d(TAG, "AnimatorListenerAdapter#onAnimationCancel");
+                    mCancelled = true;
+                }
+
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    if (DEBUG) Log.d(TAG, "AnimatorListenerAdapter#onAnimationEnd");
+                    // When ValueAnimator#cancel() is called it always calls onAnimationCancel(...)
+                    // and then onAnimationEnd(...). We, however, only want to proceed here if the
+                    // animation ended "naturally".
+                    if (!mCancelled) {
+                        onAnimationFinished();
+                    }
+                }
+            });
+        } else if (mAnimator.isRunning()) {
+            if (DEBUG) Log.d(TAG, "cancel running animation");
+            mAnimator.cancel();
+        }
+
+        final float currentValue = mIndicatorView.getAlpha();
+        if (DEBUG) Log.d(TAG, "animate alpha to " + endValue + " from " + currentValue);
+
+        mAnimator.setDuration((int) (Math.abs(currentValue - endValue) * ANIMATION_DURATION_MS));
+        mAnimator.setFloatValues(endValue);
+        mAnimator.start();
+    }
+
+    private void onAnimationFinished() {
+        if (DEBUG) Log.d(TAG, "onAnimationFinished");
+
+        if (mState == STATE_APPEARING) {
+            mState = STATE_SHOWN;
+        } else if (mState == STATE_DISAPPEARING) {
+            removeIndicatorView();
+            mState = STATE_NOT_SHOWN;
+        }
+    }
+
+    private void removeIndicatorView() {
+        if (DEBUG) Log.d(TAG, "removeIndicatorView");
+
+        final WindowManager windowManager = mContext.getSystemService(WindowManager.class);
+        if (windowManager != null) {
+            windowManager.removeView(mIndicatorView);
+        }
+
+        mIndicatorView = null;
+        mAnimator = null;
+
+        mViewAndWindowAdded = false;
+    }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
index bdf2b0c..37a763b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
@@ -22,12 +22,10 @@
 import android.os.ServiceManager;
 
 import com.android.internal.statusbar.IStatusBarService;
-import com.android.systemui.R;
 import com.android.systemui.SystemUI;
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.tv.micdisclosure.AudioRecordingDisclosureBar;
 
 import javax.inject.Inject;
 
@@ -36,11 +34,6 @@
 /**
  * Status bar implementation for "large screen" products that mostly present no on-screen nav.
  * Serves as a collection of UI components, rather than showing its own UI.
- * The following is the list of elements that constitute the TV-specific status bar:
- * <ul>
- * <li> {@link AudioRecordingDisclosureBar} - shown whenever applications are conducting audio
- * recording, discloses the responsible applications </li>
- * </ul>
  */
 @SysUISingleton
 public class TvStatusBar extends SystemUI implements CommandQueue.Callbacks {
@@ -66,11 +59,6 @@
         } catch (RemoteException ex) {
             // If the system process isn't there we're doomed anyway.
         }
-
-        if (mContext.getResources().getBoolean(R.bool.audio_recording_disclosure_enabled)) {
-            // Creating AudioRecordingDisclosureBar and just letting it run
-            new AudioRecordingDisclosureBar(mContext);
-        }
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/micdisclosure/AudioActivityObserver.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/micdisclosure/AudioActivityObserver.java
deleted file mode 100644
index bbab625..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/micdisclosure/AudioActivityObserver.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.tv.micdisclosure;
-
-import android.content.Context;
-
-import java.util.Set;
-
-/**
- * A base class for implementing observers for different kinds of activities related to audio
- * recording. These observers are to be initialized by {@link AudioRecordingDisclosureBar} and to
- * report back to it.
- */
-abstract class AudioActivityObserver {
-
-    interface OnAudioActivityStateChangeListener {
-        void onAudioActivityStateChange(boolean active, String packageName);
-    }
-
-    final Context mContext;
-
-    final OnAudioActivityStateChangeListener mListener;
-
-    AudioActivityObserver(Context context, OnAudioActivityStateChangeListener listener) {
-        mContext = context;
-        mListener = listener;
-    }
-
-    abstract void start();
-
-    abstract void stop();
-
-    abstract Set<String> getActivePackages();
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/micdisclosure/AudioRecordingDisclosureBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/micdisclosure/AudioRecordingDisclosureBar.java
deleted file mode 100644
index c9d1b71..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/micdisclosure/AudioRecordingDisclosureBar.java
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.tv.micdisclosure;
-
-import static android.provider.DeviceConfig.NAMESPACE_PRIVACY;
-import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ObjectAnimator;
-import android.annotation.IntDef;
-import android.annotation.UiThread;
-import android.content.Context;
-import android.graphics.PixelFormat;
-import android.provider.DeviceConfig;
-import android.text.TextUtils;
-import android.util.ArraySet;
-import android.util.Log;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewTreeObserver;
-import android.view.WindowManager;
-
-import com.android.systemui.R;
-import com.android.systemui.statusbar.tv.TvStatusBar;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-
-/**
- * A component of {@link TvStatusBar} responsible for notifying the user whenever an application is
- * recording audio.
- *
- * @see TvStatusBar
- */
-public class AudioRecordingDisclosureBar implements
-        AudioActivityObserver.OnAudioActivityStateChangeListener {
-    private static final String TAG = "AudioRecordingDisclosure";
-    static final boolean DEBUG = false;
-
-    // This title is used to test the microphone disclosure indicator in
-    // CtsSystemUiHostTestCases:TvMicrophoneCaptureIndicatorTest
-    private static final String LAYOUT_PARAMS_TITLE = "MicrophoneCaptureIndicator";
-
-    private static final String ENABLED_FLAG = "mic_disclosure_enabled";
-    private static final String EXEMPT_PACKAGES_LIST = "mic_disclosure_exempt_packages";
-    private static final String FORCED_PACKAGES_LIST = "mic_disclosure_forced_packages";
-
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(prefix = {"STATE_"}, value = {
-            STATE_STOPPED,
-            STATE_NOT_SHOWN,
-            STATE_APPEARING,
-            STATE_SHOWN,
-            STATE_DISAPPEARING
-    })
-    public @interface State {}
-
-    private static final int STATE_STOPPED = -1;
-    private static final int STATE_NOT_SHOWN = 0;
-    private static final int STATE_APPEARING = 1;
-    private static final int STATE_SHOWN = 2;
-    private static final int STATE_DISAPPEARING = 3;
-
-    private static final int ANIMATION_DURATION_MS = 200;
-
-    private final Context mContext;
-    private boolean mIsEnabled;
-
-    private View mIndicatorView;
-    private boolean mViewAndWindowAdded;
-    private ObjectAnimator mAnimator;
-
-    @State private int mState = STATE_STOPPED;
-
-    /**
-     * Array of the observers that monitor different aspects of the system, such as AppOps and
-     * microphone foreground services
-     */
-    private AudioActivityObserver[] mAudioActivityObservers;
-    /**
-     * Set of applications for which we make an exception and do not show the indicator. This gets
-     * populated once - in {@link #AudioRecordingDisclosureBar(Context)}.
-     */
-    private final Set<String> mExemptPackages = new ArraySet<>();
-
-    public AudioRecordingDisclosureBar(Context context) {
-        mContext = context;
-
-        // Load configs
-        reloadExemptPackages();
-
-        mIsEnabled = DeviceConfig.getBoolean(NAMESPACE_PRIVACY, ENABLED_FLAG, true);
-        // Start if enabled
-        if (mIsEnabled) {
-            start();
-        }
-
-        // Set up a config change listener
-        DeviceConfig.addOnPropertiesChangedListener(NAMESPACE_PRIVACY, mContext.getMainExecutor(),
-                mConfigChangeListener);
-    }
-
-    private void reloadExemptPackages() {
-        mExemptPackages.clear();
-        mExemptPackages.addAll(Arrays.asList(mContext.getResources().getStringArray(
-                R.array.audio_recording_disclosure_exempt_apps)));
-        mExemptPackages.addAll(
-                splitByComma(
-                        DeviceConfig.getString(NAMESPACE_PRIVACY, EXEMPT_PACKAGES_LIST, null)));
-        mExemptPackages.removeAll(
-                splitByComma(
-                        DeviceConfig.getString(NAMESPACE_PRIVACY, FORCED_PACKAGES_LIST, null)));
-    }
-
-    @UiThread
-    private void start() {
-        if (mState != STATE_STOPPED) {
-            return;
-        }
-        mState = STATE_NOT_SHOWN;
-
-        if (mAudioActivityObservers == null) {
-            mAudioActivityObservers = new AudioActivityObserver[]{
-                    new RecordAudioAppOpObserver(mContext, this),
-                    new MicrophoneForegroundServicesObserver(mContext, this),
-            };
-        }
-
-        for (int i = mAudioActivityObservers.length - 1; i >= 0; i--) {
-            mAudioActivityObservers[i].start();
-        }
-    }
-
-    @UiThread
-    private void stop() {
-        if (mState == STATE_STOPPED) {
-            return;
-        }
-        mState = STATE_STOPPED;
-
-        for (int i = mAudioActivityObservers.length - 1; i >= 0; i--) {
-            mAudioActivityObservers[i].stop();
-        }
-
-        // Remove the view if shown.
-        if (mState != STATE_NOT_SHOWN) {
-            removeIndicatorView();
-        }
-    }
-
-    @UiThread
-    @Override
-    public void onAudioActivityStateChange(boolean active, String packageName) {
-        if (DEBUG) {
-            Log.d(TAG,
-                    "onAudioActivityStateChange, packageName=" + packageName + ", active="
-                            + active);
-        }
-
-        if (mExemptPackages.contains(packageName)) {
-            if (DEBUG) Log.d(TAG, "   - exempt package: ignoring");
-            return;
-        }
-
-        if (active) {
-            showIfNeeded();
-        } else {
-            hideIndicatorIfNeeded();
-        }
-    }
-
-    @UiThread
-    private void hideIndicatorIfNeeded() {
-        // If STOPPED, NOT_SHOWN or DISAPPEARING - nothing else for us to do here.
-        if (mState != STATE_SHOWN && mState != STATE_APPEARING) return;
-
-        if (hasActiveRecorders()) {
-            return;
-        }
-
-        if (mViewAndWindowAdded) {
-            mState = STATE_DISAPPEARING;
-            animateDisappearance();
-        } else {
-            // Appearing animation has not started yet, as we were still waiting for the View to be
-            // laid out.
-            mState = STATE_NOT_SHOWN;
-            removeIndicatorView();
-        }
-    }
-
-    @UiThread
-    private void showIfNeeded() {
-        // If STOPPED, SHOWN or APPEARING - nothing else for us to do here.
-        if (mState != STATE_NOT_SHOWN && mState != STATE_DISAPPEARING) return;
-
-        if (DEBUG) Log.d(TAG, "Showing indicator");
-
-        final int prevState = mState;
-        mState = STATE_APPEARING;
-
-        if (prevState == STATE_DISAPPEARING) {
-            animateAppearance();
-            return;
-        }
-
-        // Inflate the indicator view
-        mIndicatorView = LayoutInflater.from(mContext).inflate(
-                R.layout.tv_audio_recording_indicator, null);
-
-        // 1. Set alpha to 0.
-        // 2. Wait until the window is shown and the view is laid out.
-        // 3. Start a "fade in" (alpha) animation.
-        mIndicatorView.setAlpha(0f);
-        mIndicatorView
-                .getViewTreeObserver()
-                .addOnGlobalLayoutListener(
-                        new ViewTreeObserver.OnGlobalLayoutListener() {
-                            @Override
-                            public void onGlobalLayout() {
-                                // State could have changed to NOT_SHOWN (if all the recorders are
-                                // already gone) to STOPPED (if the indicator was disabled)
-                                if (mState != STATE_APPEARING) return;
-
-                                mViewAndWindowAdded = true;
-                                // Remove the observer
-                                mIndicatorView.getViewTreeObserver().removeOnGlobalLayoutListener(
-                                        this);
-
-                                animateAppearance();
-                            }
-                        });
-
-        final boolean isLtr = mContext.getResources().getConfiguration().getLayoutDirection()
-                == View.LAYOUT_DIRECTION_LTR;
-        final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
-                WRAP_CONTENT,
-                WRAP_CONTENT,
-                WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
-                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
-                PixelFormat.TRANSLUCENT);
-        layoutParams.gravity = Gravity.TOP | (isLtr ? Gravity.RIGHT : Gravity.LEFT);
-        layoutParams.setTitle(LAYOUT_PARAMS_TITLE);
-        layoutParams.packageName = mContext.getPackageName();
-        final WindowManager windowManager = (WindowManager) mContext.getSystemService(
-                Context.WINDOW_SERVICE);
-        windowManager.addView(mIndicatorView, layoutParams);
-    }
-
-
-    private void animateAppearance() {
-        animateAlphaTo(1f);
-    }
-
-    private void animateDisappearance() {
-        animateAlphaTo(0f);
-    }
-
-    private void animateAlphaTo(final float endValue) {
-        if (mAnimator == null) {
-            if (DEBUG) Log.d(TAG, "set up animator");
-
-            mAnimator = new ObjectAnimator();
-            mAnimator.setTarget(mIndicatorView);
-            mAnimator.setProperty(View.ALPHA);
-            mAnimator.addListener(new AnimatorListenerAdapter() {
-                boolean mCancelled;
-
-                @Override
-                public void onAnimationStart(Animator animation, boolean isReverse) {
-                    if (DEBUG) Log.d(TAG, "AnimatorListenerAdapter#onAnimationStart");
-                    mCancelled = false;
-                }
-
-                @Override
-                public void onAnimationCancel(Animator animation) {
-                    if (DEBUG) Log.d(TAG, "AnimatorListenerAdapter#onAnimationCancel");
-                    mCancelled = true;
-                }
-
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                    if (DEBUG) Log.d(TAG, "AnimatorListenerAdapter#onAnimationEnd");
-                    // When ValueAnimator#cancel() is called it always calls onAnimationCancel(...)
-                    // and then onAnimationEnd(...). We, however, only want to proceed here if the
-                    // animation ended "naturally".
-                    if (!mCancelled) {
-                        onAnimationFinished();
-                    }
-                }
-            });
-        } else if (mAnimator.isRunning()) {
-            if (DEBUG) Log.d(TAG, "cancel running animation");
-            mAnimator.cancel();
-        }
-
-        final float currentValue = mIndicatorView.getAlpha();
-        if (DEBUG) Log.d(TAG, "animate alpha to " + endValue + " from " + currentValue);
-
-        mAnimator.setDuration((int) (Math.abs(currentValue - endValue) * ANIMATION_DURATION_MS));
-        mAnimator.setFloatValues(endValue);
-        mAnimator.start();
-    }
-
-    private void onAnimationFinished() {
-        if (DEBUG) Log.d(TAG, "onAnimationFinished");
-
-        if (mState == STATE_APPEARING) {
-            mState = STATE_SHOWN;
-        } else if (mState == STATE_DISAPPEARING) {
-            removeIndicatorView();
-            mState = STATE_NOT_SHOWN;
-        }
-    }
-
-    private boolean hasActiveRecorders() {
-        for (int index = mAudioActivityObservers.length - 1; index >= 0; index--) {
-            for (String activePackage : mAudioActivityObservers[index].getActivePackages()) {
-                if (mExemptPackages.contains(activePackage)) continue;
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private void removeIndicatorView() {
-        if (DEBUG) Log.d(TAG, "removeIndicatorView");
-
-        final WindowManager windowManager = (WindowManager) mContext.getSystemService(
-                Context.WINDOW_SERVICE);
-        windowManager.removeView(mIndicatorView);
-
-        mIndicatorView = null;
-        mAnimator = null;
-
-        mViewAndWindowAdded = false;
-    }
-
-    private static List<String> splitByComma(String string) {
-        return TextUtils.isEmpty(string) ? Collections.emptyList() : Arrays.asList(
-                string.split(","));
-    }
-
-    private final DeviceConfig.OnPropertiesChangedListener mConfigChangeListener =
-            new DeviceConfig.OnPropertiesChangedListener() {
-                @Override
-                public void onPropertiesChanged(DeviceConfig.Properties properties) {
-                    reloadExemptPackages();
-
-                    // Check if was enabled/disabled
-                    if (mIsEnabled != properties.getBoolean(ENABLED_FLAG, true)) {
-                        mIsEnabled = !mIsEnabled;
-                        if (mIsEnabled) {
-                            start();
-                        } else {
-                            stop();
-                        }
-                    }
-                }
-            };
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/micdisclosure/MicrophoneForegroundServicesObserver.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/micdisclosure/MicrophoneForegroundServicesObserver.java
deleted file mode 100644
index 8caf95f..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/micdisclosure/MicrophoneForegroundServicesObserver.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.tv.micdisclosure;
-
-import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE;
-
-import static com.android.systemui.statusbar.tv.micdisclosure.AudioRecordingDisclosureBar.DEBUG;
-
-import android.annotation.UiThread;
-import android.app.ActivityManager;
-import android.app.IActivityManager;
-import android.app.IProcessObserver;
-import android.content.Context;
-import android.os.RemoteException;
-import android.util.ArrayMap;
-import android.util.Log;
-import android.util.SparseArray;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * The purpose of these class is to detect packages that are running foreground services of type
- * 'microphone' and to report back to {@link AudioRecordingDisclosureBar}.
- */
-class MicrophoneForegroundServicesObserver extends AudioActivityObserver {
-    private static final String TAG = "MicrophoneForegroundServicesObserver";
-
-    private IActivityManager mActivityManager;
-    /**
-     * A dictionary that maps PIDs to the package names. We only keep track of the PIDs that are
-     * "active" (those that are running FGS with FOREGROUND_SERVICE_TYPE_MICROPHONE flag).
-     */
-    private final SparseArray<String[]> mPidToPackages = new SparseArray<>();
-    /**
-     * A dictionary that maps "active" packages to the number of the "active" processes associated
-     * with those packages. We really only need this in case when one application is running in
-     * multiple processes, so that we don't lose track of the package when one of its "active"
-     * processes ceases, while others remain "active".
-     */
-    private final Map<String, Integer> mPackageToProcessCount = new ArrayMap<>();
-
-    MicrophoneForegroundServicesObserver(Context context,
-            OnAudioActivityStateChangeListener listener) {
-        super(context, listener);
-    }
-
-    @Override
-    void start() {
-        mActivityManager = ActivityManager.getService();
-        try {
-            mActivityManager.registerProcessObserver(mProcessObserver);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Couldn't register process observer", e);
-        }
-    }
-
-    @Override
-    void stop() {
-        try {
-            mActivityManager.unregisterProcessObserver(mProcessObserver);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Couldn't unregister process observer", e);
-        }
-        mActivityManager = null;
-        mPackageToProcessCount.clear();
-    }
-
-    @Override
-    Set<String> getActivePackages() {
-        return mPackageToProcessCount.keySet();
-    }
-
-    @UiThread
-    private void onProcessForegroundServicesChanged(int pid, boolean hasMicFgs) {
-        final String[] changedPackages;
-        if (hasMicFgs) {
-            if (mPidToPackages.contains(pid)) {
-                // We are already tracking this pid - ignore.
-                changedPackages = null;
-            } else {
-                changedPackages = getPackageNames(pid);
-                mPidToPackages.append(pid, changedPackages);
-            }
-        } else {
-            changedPackages = mPidToPackages.removeReturnOld(pid);
-        }
-
-        if (changedPackages == null) {
-            return;
-        }
-
-        for (int index = changedPackages.length - 1; index >= 0; index--) {
-            final String packageName = changedPackages[index];
-            int processCount = mPackageToProcessCount.getOrDefault(packageName, 0);
-            final boolean shouldNotify;
-            if (hasMicFgs) {
-                processCount++;
-                shouldNotify = processCount == 1;
-            } else {
-                processCount--;
-                shouldNotify = processCount == 0;
-            }
-            if (processCount > 0) {
-                mPackageToProcessCount.put(packageName, processCount);
-            } else {
-                mPackageToProcessCount.remove(packageName);
-            }
-            if (shouldNotify) notifyPackageStateChanged(packageName, hasMicFgs);
-        }
-    }
-
-    @UiThread
-    private void onProcessDied(int pid) {
-        final String[] packages = mPidToPackages.removeReturnOld(pid);
-        if (packages == null) {
-            // This PID was not active - ignore.
-            return;
-        }
-
-        for (int index = packages.length - 1; index >= 0; index--) {
-            final String packageName = packages[index];
-            int processCount = mPackageToProcessCount.getOrDefault(packageName, 0);
-            if (processCount <= 0) {
-                Log.e(TAG, "Bookkeeping error, process count for " + packageName + " is "
-                        + processCount);
-                continue;
-            }
-            processCount--;
-            if (processCount > 0) {
-                mPackageToProcessCount.put(packageName, processCount);
-            } else {
-                mPackageToProcessCount.remove(packageName);
-                notifyPackageStateChanged(packageName, false);
-            }
-        }
-    }
-
-    @UiThread
-    private void notifyPackageStateChanged(String packageName, boolean active) {
-        if (DEBUG) {
-            Log.d(TAG, (active ? "New microphone fgs detected" : "Microphone fgs is gone")
-                    + ", package=" + packageName);
-        }
-
-        mListener.onAudioActivityStateChange(active, packageName);
-    }
-
-    @UiThread
-    private String[] getPackageNames(int pid) {
-        final List<ActivityManager.RunningAppProcessInfo> runningApps;
-        try {
-            runningApps = mActivityManager.getRunningAppProcesses();
-        } catch (RemoteException e) {
-            Log.d(TAG, "Couldn't get package name for pid=" + pid);
-            return null;
-        }
-        if (runningApps == null) {
-            Log.wtf(TAG, "No running apps reported");
-        }
-        for (ActivityManager.RunningAppProcessInfo app : runningApps) {
-            if (app.pid == pid) {
-                return app.pkgList;
-            }
-        }
-        return null;
-    }
-
-    private final IProcessObserver mProcessObserver = new IProcessObserver.Stub() {
-        @Override
-        public void onForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {}
-
-        @Override
-        public void onForegroundServicesChanged(int pid, int uid, int serviceTypes) {
-            mContext.getMainExecutor().execute(() -> onProcessForegroundServicesChanged(pid,
-                    (serviceTypes & FOREGROUND_SERVICE_TYPE_MICROPHONE) != 0));
-        }
-
-        @Override
-        public void onProcessDied(int pid, int uid) {
-            mContext.getMainExecutor().execute(
-                    () -> MicrophoneForegroundServicesObserver.this.onProcessDied(pid));
-        }
-    };
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/micdisclosure/RecordAudioAppOpObserver.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/micdisclosure/RecordAudioAppOpObserver.java
deleted file mode 100644
index 9a2b4a9..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/micdisclosure/RecordAudioAppOpObserver.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.tv.micdisclosure;
-
-import static com.android.systemui.statusbar.tv.micdisclosure.AudioRecordingDisclosureBar.DEBUG;
-
-import android.annotation.UiThread;
-import android.app.AppOpsManager;
-import android.content.Context;
-import android.util.ArraySet;
-import android.util.Log;
-
-import java.util.Set;
-
-/**
- * The purpose of these class is to detect packages that are conducting audio recording (according
- * to {@link AppOpsManager}) and report this to {@link AudioRecordingDisclosureBar}.
- */
-class RecordAudioAppOpObserver extends AudioActivityObserver implements
-        AppOpsManager.OnOpActiveChangedListener {
-    private static final String TAG = "RecordAudioAppOpObserver";
-
-    /**
-     * Set of the applications that currently are conducting audio recording according to {@link
-     * AppOpsManager}.
-     */
-    private final Set<String> mActiveAudioRecordingPackages = new ArraySet<>();
-
-    RecordAudioAppOpObserver(Context context, OnAudioActivityStateChangeListener listener) {
-        super(context, listener);
-    }
-
-    @Override
-    void start() {
-        if (DEBUG) {
-            Log.d(TAG, "Start");
-        }
-
-        // Register AppOpsManager callback
-        mContext.getSystemService(AppOpsManager.class)
-                .startWatchingActive(
-                        new String[]{AppOpsManager.OPSTR_RECORD_AUDIO},
-                        mContext.getMainExecutor(),
-                        this);
-    }
-
-    @Override
-    void stop() {
-        if (DEBUG) {
-            Log.d(TAG, "Stop");
-        }
-
-        // Unregister AppOpsManager callback
-        mContext.getSystemService(AppOpsManager.class).stopWatchingActive(this);
-
-        // Clean up state
-        mActiveAudioRecordingPackages.clear();
-    }
-
-    @UiThread
-    @Override
-    Set<String> getActivePackages() {
-        return mActiveAudioRecordingPackages;
-    }
-
-    @UiThread
-    @Override
-    public void onOpActiveChanged(String op, int uid, String packageName, boolean active) {
-        if (DEBUG) {
-            Log.d(TAG,
-                    "OP_RECORD_AUDIO active change, active=" + active + ", package="
-                            + packageName);
-        }
-
-        if (active) {
-            if (mActiveAudioRecordingPackages.add(packageName)) {
-                mListener.onAudioActivityStateChange(true, packageName);
-            }
-        } else {
-            if (mActiveAudioRecordingPackages.remove(packageName)) {
-                mListener.onAudioActivityStateChange(false, packageName);
-            }
-        }
-    }
-}