diff --git a/res/values/strings.xml b/res/values/strings.xml
index 6aba3c7..4c9e09f 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -12160,7 +12160,7 @@
 
     <!-- Title for media control settings [CHAR LIMIT=50]-->
     <string name="media_controls_title">Media</string>
-    <!-- Summary for media control settings [CHAR LIMIT=60]-->
+    <!-- Summary for media control settings [CHAR LIMIT=NONE]-->
     <string name="media_controls_summary">Media player in Quick Settings</string>
     <!-- Description of toggle to enable or disable the media resumption feature in quick settings [CHAR LIMIT=NONE]-->
     <string name="media_controls_resume_description">Show media player for an extended period to easily resume playback</string>
@@ -12170,8 +12170,6 @@
     <string name="media_controls_show_player">Show player</string>
     <!-- Subtext for media settings when no players can be shown [CHAR LIMIT=50] -->
     <string name="media_controls_no_players">No players available</string>
-    <!-- Subtitle for section of media control settings that shows which apps are allowed [CHAR LIMIT=50] -->
-    <string name="media_controls_apps_title">Allowed apps</string>
     <!-- Keywords for the media controls setting [CHAR LIMIT=NONE]-->
     <string name="keywords_media_controls">media</string>
 </resources>
diff --git a/res/xml/media_controls_settings.xml b/res/xml/media_controls_settings.xml
index 3ace6a0..3f0483f 100644
--- a/res/xml/media_controls_settings.xml
+++ b/res/xml/media_controls_settings.xml
@@ -28,9 +28,4 @@
         app:controller="com.android.settings.sound.MediaControlsPreferenceController"
         app:allowDividerAbove="true" />
 
-    <PreferenceCategory
-        android:key="media_controls_resumable_apps"
-        android:title="@string/media_controls_apps_title"
-        app:controller="com.android.settings.sound.ResumableMediaAppsController" />
-
 </PreferenceScreen>
diff --git a/src/com/android/settings/sound/ResumableMediaAppsController.java b/src/com/android/settings/sound/ResumableMediaAppsController.java
deleted file mode 100644
index 383cd41..0000000
--- a/src/com/android/settings/sound/ResumableMediaAppsController.java
+++ /dev/null
@@ -1,138 +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.settings.sound;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.graphics.drawable.Drawable;
-import android.provider.Settings;
-import android.service.media.MediaBrowserService;
-import android.text.TextUtils;
-import android.util.ArraySet;
-import android.util.Log;
-
-import androidx.preference.PreferenceGroup;
-import androidx.preference.PreferenceScreen;
-import androidx.preference.SwitchPreference;
-
-import com.android.settings.core.BasePreferenceController;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Section of media controls settings that contains a list of potentially resumable apps
- */
-public class ResumableMediaAppsController extends BasePreferenceController {
-    private static final String TAG = "ResumableMediaAppsCtrl";
-
-    private PreferenceGroup mPreferenceGroup;
-    private PackageManager mPackageManager;
-    private List<ResolveInfo> mResumeInfo;
-
-    public ResumableMediaAppsController(Context context, String key) {
-        super(context, key);
-        mPackageManager = mContext.getPackageManager();
-        Intent serviceIntent = new Intent(MediaBrowserService.SERVICE_INTERFACE);
-        mResumeInfo = mPackageManager.queryIntentServices(serviceIntent, 0);
-    }
-
-    @Override
-    public int getAvailabilityStatus() {
-        // Update list, since this will be called when the app goes to onStart / onPause
-        Intent serviceIntent = new Intent(MediaBrowserService.SERVICE_INTERFACE);
-        mResumeInfo = mPackageManager.queryIntentServices(serviceIntent, 0);
-        return (mResumeInfo.size() > 0) ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
-    }
-
-    @Override
-    public void displayPreference(PreferenceScreen screen) {
-        super.displayPreference(screen);
-        mPreferenceGroup = screen.findPreference(getPreferenceKey());
-        Set<String> blockedApps = getBlockedMediaApps();
-        for (ResolveInfo inf : mResumeInfo) {
-            String packageName = inf.getComponentInfo().packageName;
-            MediaSwitchPreference pref = new MediaSwitchPreference(mContext, packageName);
-            CharSequence appTitle = packageName;
-            try {
-                appTitle = mPackageManager.getApplicationLabel(
-                        mPackageManager.getApplicationInfo(packageName, 0));
-                Drawable appIcon = mPackageManager.getApplicationIcon(packageName);
-                pref.setIcon(appIcon);
-            } catch (PackageManager.NameNotFoundException e) {
-                Log.e(TAG, "Couldn't get app title", e);
-            }
-            pref.setTitle(appTitle);
-
-            pref.setOnPreferenceChangeListener((preference, status) -> {
-                MediaSwitchPreference mediaPreference = (MediaSwitchPreference) preference;
-                boolean isEnabled = (boolean) status;
-                Log.d(TAG, "preference " + mediaPreference + " changed " + isEnabled);
-
-                if (isEnabled) {
-                    blockedApps.remove(mediaPreference.getPackageName());
-                } else {
-                    blockedApps.add(mediaPreference.getPackageName());
-                }
-                setBlockedMediaApps(blockedApps);
-                return true;
-            });
-
-            pref.setChecked(!blockedApps.contains(packageName));
-            mPreferenceGroup.addPreference(pref);
-        }
-    }
-
-    class MediaSwitchPreference extends SwitchPreference {
-        private String mPackageName;
-
-        MediaSwitchPreference(Context context, String packageName) {
-            super(context);
-            mPackageName = packageName;
-        }
-
-        public String getPackageName() {
-            return mPackageName;
-        }
-    }
-
-    private Set<String> getBlockedMediaApps() {
-        String list = Settings.Secure.getString(mContext.getContentResolver(),
-                Settings.Secure.MEDIA_CONTROLS_RESUME_BLOCKED);
-        if (TextUtils.isEmpty(list)) {
-            return new ArraySet<>();
-        }
-        String[] names = list.split(":");
-        Set<String> set = new ArraySet<>(names.length);
-        Collections.addAll(set, names);
-        return set;
-    }
-
-    private void setBlockedMediaApps(Set<String> apps) {
-        if (apps == null || apps.size() == 0) {
-            Settings.Secure.putString(mContext.getContentResolver(),
-                    Settings.Secure.MEDIA_CONTROLS_RESUME_BLOCKED, "");
-            return;
-        }
-        String list = String.join(":", apps);
-        Settings.Secure.putString(mContext.getContentResolver(),
-                Settings.Secure.MEDIA_CONTROLS_RESUME_BLOCKED, list);
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/sound/ResumableMediaAppsControllerTest.java b/tests/robotests/src/com/android/settings/sound/ResumableMediaAppsControllerTest.java
deleted file mode 100644
index 797560a..0000000
--- a/tests/robotests/src/com/android/settings/sound/ResumableMediaAppsControllerTest.java
+++ /dev/null
@@ -1,168 +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.settings.sound;
-
-import static com.android.settings.core.BasePreferenceController.AVAILABLE;
-import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.provider.Settings;
-
-import androidx.preference.PreferenceGroup;
-import androidx.preference.PreferenceScreen;
-
-import com.android.settings.testutils.ResolveInfoBuilder;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@RunWith(RobolectricTestRunner.class)
-public class ResumableMediaAppsControllerTest {
-
-    private static final String KEY = "media_controls_resumable_apps";
-
-    private static final String FAKE_APP = "com.test.fakeapp1";
-
-    private Context mContext;
-    private int mOriginalQs;
-    private int mOriginalResume;
-    private String mOriginalBlocked;
-    private ContentResolver mContentResolver;
-    private ResumableMediaAppsController mController;
-    @Mock
-    private PackageManager mPackageManager;
-    @Mock
-    private PreferenceScreen mPreferenceScreen;
-    @Mock
-    private PreferenceGroup mPreferenceGroup;
-
-    @Before
-    public void setUp() {
-        mContext = spy(RuntimeEnvironment.application);
-        mContentResolver = mContext.getContentResolver();
-        mOriginalQs = Settings.Global.getInt(mContentResolver,
-                Settings.Global.SHOW_MEDIA_ON_QUICK_SETTINGS, 1);
-        mOriginalResume = Settings.Secure.getInt(mContentResolver,
-                Settings.Secure.MEDIA_CONTROLS_RESUME, 1);
-        mOriginalBlocked = Settings.Secure.getString(mContentResolver,
-                Settings.Secure.MEDIA_CONTROLS_RESUME_BLOCKED);
-
-        // Start all tests with feature enabled, nothing blocked
-        Settings.Global.putInt(mContentResolver, Settings.Global.SHOW_MEDIA_ON_QUICK_SETTINGS, 1);
-        Settings.Secure.putInt(mContentResolver, Settings.Secure.MEDIA_CONTROLS_RESUME, 1);
-        Settings.Secure.putString(mContentResolver, Settings.Secure.MEDIA_CONTROLS_RESUME_BLOCKED,
-                mOriginalBlocked);
-
-        mPreferenceScreen = mock(PreferenceScreen.class);
-        mPreferenceGroup = mock(PreferenceGroup.class);
-        mPackageManager = mock(PackageManager.class);
-
-        List<ResolveInfo> fakeInfo = new ArrayList<>();
-        fakeInfo.add(createResolveInfo(FAKE_APP));
-        when(mPackageManager.queryIntentServices(any(), anyInt())).thenReturn(fakeInfo);
-
-        when(mContext.getPackageManager()).thenReturn(mPackageManager);
-        when(mPreferenceScreen.findPreference(KEY)).thenReturn(mPreferenceGroup);
-
-        mController = new ResumableMediaAppsController(mContext, KEY);
-    }
-
-    @After
-    public void tearDown() {
-        Settings.Global.putInt(mContentResolver, Settings.Global.SHOW_MEDIA_ON_QUICK_SETTINGS,
-                mOriginalQs);
-        Settings.Secure.putInt(mContentResolver, Settings.Secure.MEDIA_CONTROLS_RESUME,
-                mOriginalResume);
-        Settings.Secure.putString(mContentResolver, Settings.Secure.MEDIA_CONTROLS_RESUME_BLOCKED,
-                mOriginalBlocked);
-    }
-
-    @Test
-    public void getAvailability_hasEligibleApps_isAvailable() {
-        // The package manager already has an eligible app from setUp()
-        assertEquals(AVAILABLE, mController.getAvailabilityStatus());
-    }
-
-    @Test
-    public void getAvailability_noEligibleApps_isConditionallyUnavailable() {
-        Context context = mock(Context.class);
-        PackageManager packageManager = mock(PackageManager.class);
-        List<ResolveInfo> fakeInfo = new ArrayList<>();
-        when(packageManager.queryIntentServices(any(), anyInt())).thenReturn(fakeInfo);
-        when(context.getPackageManager()).thenReturn(packageManager);
-        ResumableMediaAppsController controller = new ResumableMediaAppsController(context, KEY);
-
-        assertEquals(CONDITIONALLY_UNAVAILABLE, controller.getAvailabilityStatus());
-    }
-
-    @Test
-    public void displayPreference_addsApps() {
-        mController.displayPreference(mPreferenceScreen);
-        verify(mPreferenceGroup, times(1)).addPreference(any());
-    }
-
-    @Test
-    public void unblockedApp_isChecked() {
-        ArgumentCaptor<ResumableMediaAppsController.MediaSwitchPreference> argument =
-                ArgumentCaptor.forClass(ResumableMediaAppsController.MediaSwitchPreference.class);
-        mController.displayPreference(mPreferenceScreen);
-        verify(mPreferenceGroup).addPreference(argument.capture());
-        assertTrue(argument.getValue().isChecked());
-    }
-
-    @Test
-    public void blockedApp_isNotChecked() {
-        Settings.Secure.putString(mContentResolver, Settings.Secure.MEDIA_CONTROLS_RESUME_BLOCKED,
-                FAKE_APP);
-
-        ArgumentCaptor<ResumableMediaAppsController.MediaSwitchPreference> argument =
-                ArgumentCaptor.forClass(ResumableMediaAppsController.MediaSwitchPreference.class);
-        mController.displayPreference(mPreferenceScreen);
-        verify(mPreferenceGroup).addPreference(argument.capture());
-
-        assertFalse(argument.getValue().isChecked());
-    }
-
-    private ResolveInfo createResolveInfo(String name) {
-        ResolveInfoBuilder builder = new ResolveInfoBuilder(name);
-        builder.setActivity(name, name);
-        return builder.build();
-    }
-}
