summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Adrian Roos <roosa@google.com> 2024-02-05 14:49:05 +0000
committer Adrian Roos <roosa@google.com> 2024-02-05 14:50:08 +0000
commit93fe4a8f70162ecb7f4a58fc3146d8d64eb61aad (patch)
tree86f5a98f77c42399394ce46a584f7b4c9d7c8500
parentfd56681afd11fb15ffcd42137a0ff5086e4a16e4 (diff)
Remove SoundPicker2
Fixes: 323853450 Test: n/a Change-Id: I8e3af467ee039847421b818803aaf11b8e2bb4f5
-rw-r--r--packages/SoundPicker2/Android.bp46
-rw-r--r--packages/SoundPicker2/AndroidManifest.xml43
-rw-r--r--packages/SoundPicker2/OWNERS2
-rw-r--r--packages/SoundPicker2/res/drawable/ic_add.xml24
-rw-r--r--packages/SoundPicker2/res/drawable/ic_add_padded.xml22
-rw-r--r--packages/SoundPicker2/res/layout-watch/add_new_sound_item.xml36
-rw-r--r--packages/SoundPicker2/res/layout-watch/radio_with_work_badge.xml47
-rw-r--r--packages/SoundPicker2/res/layout/activity_ringtone_picker.xml21
-rw-r--r--packages/SoundPicker2/res/layout/add_new_sound_item.xml49
-rw-r--r--packages/SoundPicker2/res/layout/fragment_ringtone_picker.xml23
-rw-r--r--packages/SoundPicker2/res/layout/fragment_tabbed_dialog.xml31
-rw-r--r--packages/SoundPicker2/res/layout/radio_with_work_badge.xml50
-rw-r--r--packages/SoundPicker2/res/raw/default_alarm_alert.ogg0
-rw-r--r--packages/SoundPicker2/res/raw/default_notification_sound.ogg0
-rw-r--r--packages/SoundPicker2/res/raw/default_ringtone.ogg0
-rw-r--r--packages/SoundPicker2/res/values/config.xml25
-rw-r--r--packages/SoundPicker2/res/values/strings.xml47
-rw-r--r--packages/SoundPicker2/res/values/styles.xml22
-rw-r--r--packages/SoundPicker2/src/com/android/soundpicker/BasePickerFragment.java312
-rw-r--r--packages/SoundPicker2/src/com/android/soundpicker/CheckedListItem.java67
-rw-r--r--packages/SoundPicker2/src/com/android/soundpicker/ListeningExecutorServiceFactory.java44
-rw-r--r--packages/SoundPicker2/src/com/android/soundpicker/LocalizedCursor.java117
-rw-r--r--packages/SoundPicker2/src/com/android/soundpicker/RingtoneFactory.java62
-rw-r--r--packages/SoundPicker2/src/com/android/soundpicker/RingtoneListHandler.java222
-rw-r--r--packages/SoundPicker2/src/com/android/soundpicker/RingtoneListViewAdapter.java264
-rw-r--r--packages/SoundPicker2/src/com/android/soundpicker/RingtoneManagerFactory.java49
-rw-r--r--packages/SoundPicker2/src/com/android/soundpicker/RingtoneOverlayService.java113
-rw-r--r--packages/SoundPicker2/src/com/android/soundpicker/RingtonePickerActivity.java218
-rw-r--r--packages/SoundPicker2/src/com/android/soundpicker/RingtonePickerApplication.java28
-rw-r--r--packages/SoundPicker2/src/com/android/soundpicker/RingtonePickerViewModel.java340
-rw-r--r--packages/SoundPicker2/src/com/android/soundpicker/RingtoneReceiver.java36
-rw-r--r--packages/SoundPicker2/src/com/android/soundpicker/SoundPickerFragment.java122
-rw-r--r--packages/SoundPicker2/src/com/android/soundpicker/TabbedDialogFragment.java180
-rw-r--r--packages/SoundPicker2/src/com/android/soundpicker/VibrationPickerFragment.java52
-rw-r--r--packages/SoundPicker2/src/com/android/soundpicker/ViewPagerAdapter.java70
-rw-r--r--packages/SoundPicker2/tests/Android.bp38
-rw-r--r--packages/SoundPicker2/tests/AndroidManifest.xml11
-rw-r--r--packages/SoundPicker2/tests/src/com/android/soundpicker/RingtoneListHandlerTest.java167
-rw-r--r--packages/SoundPicker2/tests/src/com/android/soundpicker/RingtonePickerViewModelTest.java534
39 files changed, 0 insertions, 3534 deletions
diff --git a/packages/SoundPicker2/Android.bp b/packages/SoundPicker2/Android.bp
deleted file mode 100644
index f4d8bf2c76b5..000000000000
--- a/packages/SoundPicker2/Android.bp
+++ /dev/null
@@ -1,46 +0,0 @@
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "frameworks_base_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["frameworks_base_license"],
-}
-
-android_library {
- name: "SoundPicker2Lib",
- srcs: [
- "src/**/*.java",
- ],
- resource_dirs: [
- "res",
- ],
- static_libs: [
- "androidx.appcompat_appcompat",
- "hilt_android",
- "guava",
- "androidx.recyclerview_recyclerview",
- "androidx-constraintlayout_constraintlayout",
- "androidx.viewpager2_viewpager2",
- "com.google.android.material_material",
- ],
-}
-
-android_app {
- name: "SoundPicker2",
- defaults: ["platform_app_defaults"],
- manifest: "AndroidManifest.xml",
- static_libs: ["SoundPicker2Lib"],
- platform_apis: true,
- certificate: "media",
- privileged: true,
-
- optimize: {
- enabled: true,
- optimize: true,
- shrink: true,
- shrink_resources: true,
- obfuscate: false,
- proguard_compatibility: false,
- },
-}
diff --git a/packages/SoundPicker2/AndroidManifest.xml b/packages/SoundPicker2/AndroidManifest.xml
deleted file mode 100644
index 934b003c605c..000000000000
--- a/packages/SoundPicker2/AndroidManifest.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.soundpicker"
- android:sharedUserId="android.media">
-
- <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-
- <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
- <uses-permission android:name="android.permission.RECEIVE_DEVICE_CUSTOMIZATION_READY" />
- <uses-permission android:name="android.permission.WRITE_SETTINGS" />
-
- <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
-
- <application
- android:name=".RingtonePickerApplication"
- android:allowBackup="false"
- android:label="@string/app_label"
- android:theme="@style/Theme.AppCompat"
- android:supportsRtl="true">
- <receiver android:name="RingtoneReceiver"
- android:exported="true">
- <intent-filter>
- <action android:name="android.intent.action.DEVICE_CUSTOMIZATION_READY"/>
- </intent-filter>
- </receiver>
-
- <service android:name="RingtoneOverlayService" />
-
- <activity android:name="RingtonePickerActivity"
- android:theme="@style/Theme.AppCompat.Dialog"
- android:enabled="@*android:bool/config_defaultRingtonePickerEnabled"
- android:excludeFromRecents="true"
- android:exported="true">
- <intent-filter>
- <action android:name="android.intent.action.RINGTONE_PICKER" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.RINGTONE_PICKER_SOUND" />
- <category android:name="android.intent.category.RINGTONE_PICKER_VIBRATION" />
- <category android:name="android.intent.category.RINGTONE_PICKER_RINGTONE" />
- </intent-filter>
- </activity>
- </application>
-</manifest>
diff --git a/packages/SoundPicker2/OWNERS b/packages/SoundPicker2/OWNERS
deleted file mode 100644
index 5bf46e039e96..000000000000
--- a/packages/SoundPicker2/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Haptics team works on the SoundPicker
-include platform/frameworks/base:/services/core/java/com/android/server/vibrator/OWNERS
diff --git a/packages/SoundPicker2/res/drawable/ic_add.xml b/packages/SoundPicker2/res/drawable/ic_add.xml
deleted file mode 100644
index 22b3fe9176e5..000000000000
--- a/packages/SoundPicker2/res/drawable/ic_add.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
- 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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24.0dp"
- android:height="24.0dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
- <path
- android:fillColor="?android:attr/colorAccent"
- android:pathData="M38.0,26.0L26.0,26.0l0.0,12.0l-4.0,0.0L22.0,26.0L10.0,26.0l0.0,-4.0l12.0,0.0L22.0,10.0l4.0,0.0l0.0,12.0l12.0,0.0l0.0,4.0z"/>
-</vector> \ No newline at end of file
diff --git a/packages/SoundPicker2/res/drawable/ic_add_padded.xml b/packages/SoundPicker2/res/drawable/ic_add_padded.xml
deleted file mode 100644
index c376867896d0..000000000000
--- a/packages/SoundPicker2/res/drawable/ic_add_padded.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<!--
- Copyright (C) 2017 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.
--->
-
-<inset xmlns:android="http://schemas.android.com/apk/res/android"
- android:drawable="@drawable/ic_add"
- android:insetTop="4dp"
- android:insetRight="4dp"
- android:insetBottom="4dp"
- android:insetLeft="4dp"/>
diff --git a/packages/SoundPicker2/res/layout-watch/add_new_sound_item.xml b/packages/SoundPicker2/res/layout-watch/add_new_sound_item.xml
deleted file mode 100644
index edfc0aba5be7..000000000000
--- a/packages/SoundPicker2/res/layout-watch/add_new_sound_item.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2017 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.
--->
-
-<!--
- Currently, no file manager app on watch could handle ACTION_GET_CONTENT intent.
- Make the visibility to "gone" to prevent failures.
- -->
-<TextView xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/add_new_sound_text"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:minHeight="?android:attr/listPreferredItemHeightSmall"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:text="@null"
- android:textColor="?android:attr/colorAccent"
- android:gravity="center_vertical"
- android:paddingStart="?android:attr/listPreferredItemPaddingStart"
- android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
- android:drawableStart="@drawable/ic_add_padded"
- android:drawablePadding="8dp"
- android:ellipsize="marquee"
- android:visibility="gone" />
diff --git a/packages/SoundPicker2/res/layout-watch/radio_with_work_badge.xml b/packages/SoundPicker2/res/layout-watch/radio_with_work_badge.xml
deleted file mode 100644
index ee29a3710143..000000000000
--- a/packages/SoundPicker2/res/layout-watch/radio_with_work_badge.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 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.
--->
-<com.android.soundpicker.CheckedListItem xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:gravity="center_vertical"
- android:background="?android:attr/selectableItemBackground"
- >
-
- <CheckedTextView
- android:id="@+id/checked_text_view"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:minHeight="?android:attr/listPreferredItemHeightSmall"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:textColor="?android:attr/textColorAlertDialogListItem"
- android:gravity="center_vertical"
- android:paddingStart="?android:attr/listPreferredItemPaddingStart"
- android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
- android:drawableStart="?android:attr/listChoiceIndicatorSingle"
- android:drawablePadding="8dp"
- android:ellipsize="marquee"
- android:layout_toLeftOf="@+id/work_icon"
- android:maxLines="3" />
-
- <ImageView
- android:id="@id/work_icon"
- android:layout_width="18dp"
- android:layout_height="18dp"
- android:layout_alignParentRight="true"
- android:layout_centerVertical="true"
- android:scaleType="centerCrop"
- android:layout_marginRight="20dp" />
-</com.android.soundpicker.CheckedListItem>
diff --git a/packages/SoundPicker2/res/layout/activity_ringtone_picker.xml b/packages/SoundPicker2/res/layout/activity_ringtone_picker.xml
deleted file mode 100644
index 6fc60801ad3a..000000000000
--- a/packages/SoundPicker2/res/layout/activity_ringtone_picker.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2023 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:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="match_parent"/> \ No newline at end of file
diff --git a/packages/SoundPicker2/res/layout/add_new_sound_item.xml b/packages/SoundPicker2/res/layout/add_new_sound_item.xml
deleted file mode 100644
index 024b97ef23be..000000000000
--- a/packages/SoundPicker2/res/layout/add_new_sound_item.xml
+++ /dev/null
@@ -1,49 +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.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:gravity="center_vertical"
- android:background="?android:attr/selectableItemBackground"
- android:focusable="true"
- android:clickable="true">
-
- <ImageView
- android:layout_width="24dp"
- android:layout_height="24dp"
- android:layout_alignParentRight="true"
- android:layout_centerVertical="true"
- android:scaleType="centerCrop"
- android:layout_marginRight="24dp"
- android:layout_marginLeft="24dp"
- android:src="@drawable/ic_add"/>
-
- <TextView
- android:id="@+id/add_new_sound_text"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:minHeight="?android:attr/listPreferredItemHeightSmall"
- android:text="@null"
- android:textColor="?android:attr/colorAccent"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:maxLines="3"
- android:gravity="center_vertical"
- android:paddingEnd="?android:attr/dialogPreferredPadding"
- android:drawablePadding="20dp"
- android:ellipsize="marquee"/>
-</LinearLayout> \ No newline at end of file
diff --git a/packages/SoundPicker2/res/layout/fragment_ringtone_picker.xml b/packages/SoundPicker2/res/layout/fragment_ringtone_picker.xml
deleted file mode 100644
index 787f92ec06d6..000000000000
--- a/packages/SoundPicker2/res/layout/fragment_ringtone_picker.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2023 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.
--->
-<androidx.recyclerview.widget.RecyclerView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:id="@+id/recycler_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
-/> \ No newline at end of file
diff --git a/packages/SoundPicker2/res/layout/fragment_tabbed_dialog.xml b/packages/SoundPicker2/res/layout/fragment_tabbed_dialog.xml
deleted file mode 100644
index 7efd91191b79..000000000000
--- a/packages/SoundPicker2/res/layout/fragment_tabbed_dialog.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2023 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:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- <com.google.android.material.tabs.TabLayout
- android:id="@+id/tabLayout"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"/>
- <androidx.viewpager2.widget.ViewPager2
- android:id="@+id/masterViewPager"
- android:paddingTop="12dp"
- android:paddingBottom="12dp"
- android:layout_width="match_parent"
- android:layout_height="match_parent"/>
-</LinearLayout> \ No newline at end of file
diff --git a/packages/SoundPicker2/res/layout/radio_with_work_badge.xml b/packages/SoundPicker2/res/layout/radio_with_work_badge.xml
deleted file mode 100644
index 36ac93ed630b..000000000000
--- a/packages/SoundPicker2/res/layout/radio_with_work_badge.xml
+++ /dev/null
@@ -1,50 +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.
--->
-
-<com.android.soundpicker.CheckedListItem
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:gravity="center_vertical"
- android:background="?android:attr/selectableItemBackground"
- android:focusable="true"
- android:clickable="true">
-
- <CheckedTextView
- android:id="@+id/checked_text_view"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:minHeight="?android:attr/listPreferredItemHeightSmall"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:textColor="?android:attr/textColorAlertDialogListItem"
- android:gravity="center_vertical"
- android:paddingStart="20dp"
- android:paddingEnd="?android:attr/dialogPreferredPadding"
- android:drawableStart="?android:attr/listChoiceIndicatorSingle"
- android:drawablePadding="20dp"
- android:ellipsize="marquee"
- android:layout_toLeftOf="@+id/work_icon"
- android:maxLines="3"/>
-
- <ImageView
- android:id="@id/work_icon"
- android:layout_width="18dp"
- android:layout_height="18dp"
- android:layout_alignParentRight="true"
- android:layout_centerVertical="true"
- android:scaleType="centerCrop"
- android:layout_marginRight="20dp"/>
-</com.android.soundpicker.CheckedListItem>
diff --git a/packages/SoundPicker2/res/raw/default_alarm_alert.ogg b/packages/SoundPicker2/res/raw/default_alarm_alert.ogg
deleted file mode 100644
index e69de29bb2d1..000000000000
--- a/packages/SoundPicker2/res/raw/default_alarm_alert.ogg
+++ /dev/null
diff --git a/packages/SoundPicker2/res/raw/default_notification_sound.ogg b/packages/SoundPicker2/res/raw/default_notification_sound.ogg
deleted file mode 100644
index e69de29bb2d1..000000000000
--- a/packages/SoundPicker2/res/raw/default_notification_sound.ogg
+++ /dev/null
diff --git a/packages/SoundPicker2/res/raw/default_ringtone.ogg b/packages/SoundPicker2/res/raw/default_ringtone.ogg
deleted file mode 100644
index e69de29bb2d1..000000000000
--- a/packages/SoundPicker2/res/raw/default_ringtone.ogg
+++ /dev/null
diff --git a/packages/SoundPicker2/res/values/config.xml b/packages/SoundPicker2/res/values/config.xml
deleted file mode 100644
index 4e237a2f1644..000000000000
--- a/packages/SoundPicker2/res/values/config.xml
+++ /dev/null
@@ -1,25 +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.
--->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. Do not translate.
-
- NOTE: The naming convention is "config_camelCaseValue". -->
-<resources xmlns:android="http://schemas.android.com/apk/res/android">
- <!-- True if the ringtone picker should show the ok/cancel buttons. If it is not shown, the
- ringtone will be automatically selected when the picker is closed. -->
- <bool name="config_showOkCancelButtons">true</bool>
-</resources>
diff --git a/packages/SoundPicker2/res/values/strings.xml b/packages/SoundPicker2/res/values/strings.xml
deleted file mode 100644
index ab7b95a09028..000000000000
--- a/packages/SoundPicker2/res/values/strings.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- Choice in the ringtone picker. If chosen, the default ringtone will be used. -->
- <string name="ringtone_default">Default ringtone</string>
-
- <!-- Choice in the notification sound picker. If chosen, the default notification sound will be
- used. -->
- <string name="notification_sound_default">Default notification sound</string>
-
- <!-- Choice in the alarm sound picker. If chosen, the default alarm sound will be used. -->
- <string name="alarm_sound_default">Default alarm sound</string>
-
- <!-- Text for the RingtonePicker item that allows adding a new ringtone. -->
- <string name="add_ringtone_text">Add ringtone</string>
- <!-- Text for the RingtonePicker item that allows adding a new alarm. -->
- <string name="add_alarm_text">Add alarm</string>
- <!-- Text for the RingtonePicker item that allows adding a new notification. -->
- <string name="add_notification_text">Add notification</string>
- <!-- Text for the RingtonePicker item ContextMenu that allows deleting a custom ringtone. -->
- <string name="delete_ringtone_text">Delete</string>
- <!-- Text for the Toast displayed when adding a custom ringtone fails. -->
- <string name="unable_to_add_ringtone">Unable to add custom ringtone</string>
- <!-- Text for the Toast displayed when deleting a custom ringtone fails. -->
- <string name="unable_to_delete_ringtone">Unable to delete custom ringtone</string>
-
- <!-- Text for the name of the app. [CHAR LIMIT=12] -->
- <string name="app_label">Sounds</string>
-
- <string name="empty_list">The list is empty</string>
- <string name="sound_page_title">Sound</string>
- <string name="vibration_page_title">Vibration</string>
-</resources>
diff --git a/packages/SoundPicker2/res/values/styles.xml b/packages/SoundPicker2/res/values/styles.xml
deleted file mode 100644
index d22d9c43d0fb..000000000000
--- a/packages/SoundPicker2/res/values/styles.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 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 xmlns:android="http://schemas.android.com/apk/res/android">
-
- <style name="PickerDialogTheme" parent="@*android:style/Theme.DeviceDefault.Settings.Dialog">
- </style>
-
-</resources>
diff --git a/packages/SoundPicker2/src/com/android/soundpicker/BasePickerFragment.java b/packages/SoundPicker2/src/com/android/soundpicker/BasePickerFragment.java
deleted file mode 100644
index 4fc2a86537c1..000000000000
--- a/packages/SoundPicker2/src/com/android/soundpicker/BasePickerFragment.java
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * Copyright (C) 2023 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.soundpicker;
-
-import android.app.Activity;
-import android.content.ContentProvider;
-import android.content.Intent;
-import android.graphics.drawable.Drawable;
-import android.media.RingtoneManager;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.provider.MediaStore;
-import android.util.Log;
-import android.view.View;
-
-import androidx.annotation.NonNull;
-import androidx.fragment.app.Fragment;
-import androidx.lifecycle.ViewModelProvider;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-
-import dagger.hilt.android.AndroidEntryPoint;
-
-import java.util.Objects;
-
-/**
- * Base class for generic picker fragments.
- *
- * <p>This fragment displays a recycler view that is populated by a {@link RingtoneListViewAdapter}
- * with data provided by a {@link RingtoneListHandler}. Each item can be selected on click,
- * which also triggers a ringtone preview performed by the shared {@link RingtonePickerViewModel}.
- * The ringtone preview uses the selection state of all picker fragments (e.g. sound selected by
- * one fragment and vibration selected by another).
- */
-@AndroidEntryPoint(Fragment.class)
-public abstract class BasePickerFragment extends Hilt_BasePickerFragment implements
- RingtoneListViewAdapter.Callbacks {
-
- private static final String TAG = "BasePickerFragment";
- private static final String COLUMN_LABEL = MediaStore.Audio.Media.TITLE;
- private boolean mIsManagedProfile;
- private Drawable mWorkIconDrawable;
-
- protected RingtoneListViewAdapter mRingtoneListViewAdapter;
- protected RecyclerView mRecyclerView;
- protected RingtonePickerViewModel.Config mPickerConfig;
- protected RingtonePickerViewModel mRingtonePickerViewModel;
- protected RingtoneListHandler.Config mRingtoneListConfig;
- protected RingtoneListHandler mRingtoneListHandler;
-
- public BasePickerFragment() {
- super(R.layout.fragment_ringtone_picker);
- }
-
- @Override
- public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
- mRingtonePickerViewModel = new ViewModelProvider(requireActivity()).get(
- RingtonePickerViewModel.class);
- mRingtoneListHandler = getRingtoneListHandler();
- mRecyclerView = view.requireViewById(R.id.recycler_view);
-
- mPickerConfig = mRingtonePickerViewModel.getPickerConfig();
- mRingtoneListConfig = mRingtoneListHandler.getRingtoneListConfig();
-
- mIsManagedProfile = UserManager.get(requireActivity()).isManagedProfile(
- mPickerConfig.userId);
-
- mRingtoneListViewAdapter = createRingtoneListViewAdapter();
- mRecyclerView.setHasFixedSize(true);
- mRecyclerView.setAdapter(mRingtoneListViewAdapter);
- mRecyclerView.setLayoutManager(new LinearLayoutManager(requireActivity()));
- setSelectedItem(mRingtoneListHandler.getSelectedItemPosition());
- prepareRecyclerView(mRecyclerView);
- }
-
- @Override
- public boolean isWorkRingtone(int position) {
- if (!mIsManagedProfile) {
- return false;
- }
-
- /*
- * Display the work icon if the ringtone belongs to a work profile. We
- * can tell that a ringtone belongs to a work profile if the picker user
- * is a managed profile, the ringtone Uri is in external storage, and
- * either the uri has no user id or has the id of the picker user
- */
- Uri currentUri = mRingtoneListHandler.getRingtoneUri(position);
- int uriUserId = ContentProvider.getUserIdFromUri(currentUri,
- mPickerConfig.userId);
- Uri uriWithoutUserId = ContentProvider.getUriWithoutUserId(currentUri);
-
- return uriUserId == mPickerConfig.userId
- && uriWithoutUserId.toString().startsWith(
- MediaStore.Audio.Media.EXTERNAL_CONTENT_URI.toString());
- }
-
- @Override
- public Drawable getWorkIconDrawable() {
- if (mWorkIconDrawable == null) {
- mWorkIconDrawable = requireActivity().getPackageManager()
- .getUserBadgeForDensityNoBackground(
- UserHandle.of(mPickerConfig.userId), /* density= */ -1);
- }
-
- return mWorkIconDrawable;
- }
-
- @Override
- public void onRingtoneSelected(int position) {
- setSelectedItem(position);
-
- // In the buttonless (watch-only) version, preemptively set our result since
- // we won't have another chance to do so before the activity closes.
- if (!mPickerConfig.showOkCancelButtons) {
- setSuccessResultWithSelectedRingtone();
- }
-
- // Play clip
- mRingtonePickerViewModel.playRingtone();
- }
-
- @Override
- public void onAddRingtoneSelected() {
- addRingtoneAsync();
- }
-
- /**
- * Sets up the list by adding fixed items to the top and bottom, if required. And sets the
- * selected item in the list.
- * @param recyclerView The recyclerview that contains the list of displayed items.
- */
- protected void prepareRecyclerView(@NonNull RecyclerView recyclerView) {
- // Reset the static item count, as this method can be called multiple times
- mRingtoneListHandler.resetFixedItems();
-
- if (mRingtoneListConfig.hasDefaultItem) {
- int defaultItemPos = addDefaultRingtoneItem();
-
- if (getSelectedItem() < 0
- && RingtoneManager.isDefault(mRingtoneListConfig.initialSelectedUri)) {
- setSelectedItem(defaultItemPos);
- }
- }
-
- if (mRingtoneListConfig.hasSilentItem) {
- int silentItemPos = addSilentItem();
-
- // The 'Silent' item should use a null Uri
- if (getSelectedItem() < 0
- && mRingtoneListConfig.initialSelectedUri == null) {
- setSelectedItem(silentItemPos);
- }
- }
-
- if (getSelectedItem() < 0) {
- setSelectedItem(mRingtoneListHandler.getRingtonePosition(
- mRingtoneListConfig.initialSelectedUri));
- }
-
- // In the buttonless (watch-only) version, preemptively set our result since we won't
- // have another chance to do so before the activity closes.
- if (!mPickerConfig.showOkCancelButtons) {
- setSuccessResultWithSelectedRingtone();
- }
-
- addNewRingtoneItem();
-
- // Enable context menu in ringtone items
- registerForContextMenu(recyclerView);
- }
-
- /**
- * Returns the fragment's sound/vibration list handler.
- * @return The ringtone list handler.
- */
- protected abstract RingtoneListHandler getRingtoneListHandler();
-
- /**
- * Starts the process to add a new ringtone to the list of ringtones asynchronously.
- * Currently, only works for adding sound files.
- */
- protected abstract void addRingtoneAsync();
-
- /**
- * Adds an item to the end of the list that can be used to add new ringtones to the list.
- * Currently, only works for adding sound files.
- */
- protected abstract void addNewRingtoneItem();
-
- protected int getSelectedItem() {
- return mRingtoneListHandler.getSelectedItemPosition();
- }
-
- /**
- * Returns the selected URI to the caller activity.
- */
- protected void setSuccessResultWithSelectedRingtone() {
- requireActivity().setResult(Activity.RESULT_OK,
- new Intent().putExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI,
- mRingtonePickerViewModel.getSelectedRingtoneUri()));
- }
-
- /**
- * Creates a ringtone recyclerview adapter using the ringtone manager cursor.
- * @return The created RingtoneListViewAdapter.
- */
- protected RingtoneListViewAdapter createRingtoneListViewAdapter() {
- LocalizedCursor cursor = new LocalizedCursor(
- mRingtoneListHandler.getRingtoneCursor(), getResources(), COLUMN_LABEL);
- return new RingtoneListViewAdapter(cursor, /* RingtoneListViewAdapterCallbacks= */ this);
- }
-
- /**
- * Sets the selected item in the list and scroll to the position in the recyclerview.
- * @param pos the position of the selected item in the list.
- */
- protected void setSelectedItem(int pos) {
- Objects.requireNonNull(mRingtoneListViewAdapter);
- mRingtoneListHandler.setSelectedItemPosition(pos);
- mRingtoneListViewAdapter.setSelectedItem(pos);
- mRingtoneListHandler.setSelectedItemId(mRingtoneListViewAdapter.getItemId(pos));
- mRecyclerView.scrollToPosition(pos);
- }
-
- /**
- * Adds a fixed item to the fixed items list . A fixed item is one that is not from
- * the RingtoneManager.
- *
- * @param textResId The resource ID of the text for the item.
- * @return The index of the inserted fixed item in the adapter.
- */
- protected int addFixedItem(int textResId) {
- return mRingtoneListViewAdapter.addTitleForFixedItem(textResId);
- }
-
- /**
- * Re-query RingtoneManager for the most recent set of installed ringtones. May move the
- * selected item position to match the new position of the chosen ringtone.
- * <p>
- * This should only need to happen after adding or removing a ringtone.
- */
- protected void requeryForAdapter() {
- mRingtonePickerViewModel.reinit();
- // Refresh and set a new cursor, and closing the old one.
- mRingtoneListViewAdapter = createRingtoneListViewAdapter();
- mRecyclerView.setAdapter(mRingtoneListViewAdapter);
- prepareRecyclerView(mRecyclerView);
-
- // Update selected item location.
- for (int i = 0; i < mRingtoneListViewAdapter.getItemCount(); i++) {
- if (mRingtoneListViewAdapter.getItemId(i)
- == mRingtoneListHandler.getSelectedItemId()) {
- setSelectedItem(i);
- return;
- }
- }
-
- // If selected item is still unknown, then set it to the default item, if available.
- // If it's not available, then attempt to set it to the silent item in the list.
- int selectedPosition = mRingtoneListHandler.getDefaultItemPosition();
-
- if (selectedPosition < 0) {
- selectedPosition = mRingtoneListHandler.getSilentItemPosition();
- }
-
- setSelectedItem(selectedPosition);
- }
-
- private int addDefaultRingtoneItem() {
- int defaultItemPosInAdapter = addFixedItem(
- RingtonePickerViewModel.getDefaultRingtoneItemTextByType(
- mPickerConfig.ringtoneType));
- int defaultItemPosInListHandler = mRingtoneListHandler.addDefaultItem();
-
- if (defaultItemPosInAdapter != defaultItemPosInListHandler) {
- Log.wtf(TAG, "Default item position in adapter and list handler must match.");
- return RingtoneListHandler.ITEM_POSITION_UNKNOWN;
- }
-
- return defaultItemPosInListHandler;
- }
-
- private int addSilentItem() {
- int silentItemPosInAdapter = addFixedItem(com.android.internal.R.string.ringtone_silent);
- int silentItemPosInListHandler = mRingtoneListHandler.addSilentItem();
-
- if (silentItemPosInAdapter != silentItemPosInListHandler) {
- Log.wtf(TAG, "Silent item position in adapter and list handler must match.");
- return RingtoneListHandler.ITEM_POSITION_UNKNOWN;
- }
-
- return silentItemPosInListHandler;
- }
-}
diff --git a/packages/SoundPicker2/src/com/android/soundpicker/CheckedListItem.java b/packages/SoundPicker2/src/com/android/soundpicker/CheckedListItem.java
deleted file mode 100644
index 819ae987269d..000000000000
--- a/packages/SoundPicker2/src/com/android/soundpicker/CheckedListItem.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.soundpicker;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.Checkable;
-import android.widget.CheckedTextView;
-import android.widget.RelativeLayout;
-
-/**
- * The {@link CheckedListItem} is a layout item that represents a ringtone, and is used in
- * {@link RingtonePickerActivity}. It contains the ringtone's name, and a work badge to right of the
- * name if the ringtone belongs to a work profile.
- */
-public class CheckedListItem extends RelativeLayout implements Checkable {
-
- public CheckedListItem(Context context) {
- super(context);
- }
-
- public CheckedListItem(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public CheckedListItem(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- }
-
- public CheckedListItem(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
- super(context, attrs, defStyleAttr, defStyleRes);
- }
-
- @Override
- public void setChecked(boolean checked) {
- getCheckedTextView().setChecked(checked);
- }
-
- @Override
- public boolean isChecked() {
- return getCheckedTextView().isChecked();
- }
-
- @Override
- public void toggle() {
- getCheckedTextView().toggle();
- }
-
- private CheckedTextView getCheckedTextView() {
- return (CheckedTextView) findViewById(R.id.checked_text_view);
- }
-
-}
diff --git a/packages/SoundPicker2/src/com/android/soundpicker/ListeningExecutorServiceFactory.java b/packages/SoundPicker2/src/com/android/soundpicker/ListeningExecutorServiceFactory.java
deleted file mode 100644
index afdbf053ac22..000000000000
--- a/packages/SoundPicker2/src/com/android/soundpicker/ListeningExecutorServiceFactory.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2023 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.soundpicker;
-
-import com.google.common.util.concurrent.ListeningExecutorService;
-import com.google.common.util.concurrent.MoreExecutors;
-
-import java.util.concurrent.Executors;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-/**
- * A factory class used to create {@link ListeningExecutorService}.
- */
-@Singleton
-public class ListeningExecutorServiceFactory {
-
- @Inject
- ListeningExecutorServiceFactory() {
- }
-
- /**
- * Returns a single thread {@link ListeningExecutorService}.
- *
- */
- public ListeningExecutorService createSingleThreadExecutor() {
- return MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor());
- }
-}
diff --git a/packages/SoundPicker2/src/com/android/soundpicker/LocalizedCursor.java b/packages/SoundPicker2/src/com/android/soundpicker/LocalizedCursor.java
deleted file mode 100644
index 83d04a345f8b..000000000000
--- a/packages/SoundPicker2/src/com/android/soundpicker/LocalizedCursor.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2023 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.soundpicker;
-
-import android.content.res.Resources;
-import android.database.Cursor;
-import android.database.CursorWrapper;
-import android.util.Log;
-import android.util.TypedValue;
-
-import androidx.annotation.Nullable;
-
-import java.util.Locale;
-import java.util.regex.Pattern;
-
-/**
- * A cursor wrapper class mainly used to guarantee getting a ringtone title
- */
-final class LocalizedCursor extends CursorWrapper {
-
- private static final String TAG = "LocalizedCursor";
- private static final String SOUND_NAME_RES_PREFIX = "sound_name_";
-
- private final int mTitleIndex;
- private final Resources mResources;
- private final Pattern mSanitizePattern;
- private final String mNamePrefix;
-
- LocalizedCursor(Cursor cursor, Resources resources, String columnLabel) {
- super(cursor);
- mTitleIndex = mCursor.getColumnIndex(columnLabel);
- mResources = resources;
- mSanitizePattern = Pattern.compile("[^a-zA-Z0-9]");
- if (mTitleIndex == -1) {
- Log.e(TAG, "No index for column " + columnLabel);
- mNamePrefix = null;
- } else {
- mNamePrefix = buildNamePrefix(mResources);
- }
- }
-
- /**
- * Builds the prefix for the name of the resource to look up.
- * The format is: "ResourcePackageName::ResourceTypeName/" (the type name is expected to be
- * "string" but let's not hardcode it).
- * Here we use an existing resource "notification_sound_default" which is always expected to be
- * found.
- *
- * @param resources Application's resources
- * @return the built name prefix, or null if failed to build.
- */
- @Nullable
- private static String buildNamePrefix(Resources resources) {
- try {
- return String.format("%s:%s/%s",
- resources.getResourcePackageName(R.string.notification_sound_default),
- resources.getResourceTypeName(R.string.notification_sound_default),
- SOUND_NAME_RES_PREFIX);
- } catch (Resources.NotFoundException e) {
- Log.e(TAG, "Failed to build the prefix for the name of the resource.", e);
- }
-
- return null;
- }
-
- /**
- * Process resource name to generate a valid resource name.
- *
- * @return a non-null String
- */
- private String sanitize(String input) {
- if (input == null) {
- return "";
- }
- return mSanitizePattern.matcher(input).replaceAll("_").toLowerCase(Locale.ROOT);
- }
-
- @Override
- public String getString(int columnIndex) {
- final String defaultName = mCursor.getString(columnIndex);
- if ((columnIndex != mTitleIndex) || (mNamePrefix == null)) {
- return defaultName;
- }
- TypedValue value = new TypedValue();
- try {
- // the name currently in the database is used to derive a name to match
- // against resource names in this package
- mResources.getValue(mNamePrefix + sanitize(defaultName), value,
- /* resolveRefs= */ false);
- } catch (Resources.NotFoundException e) {
- Log.d(TAG, "Failed to get localized string. Using default string instead.", e);
- return defaultName;
- }
- if ((value != null) && (value.type == TypedValue.TYPE_STRING)) {
- Log.d(TAG, String.format("Replacing name %s with %s",
- defaultName, value.string.toString()));
- return value.string.toString();
- } else {
- Log.e(TAG, "Invalid value when looking up localized name, using " + defaultName);
- return defaultName;
- }
- }
-}
diff --git a/packages/SoundPicker2/src/com/android/soundpicker/RingtoneFactory.java b/packages/SoundPicker2/src/com/android/soundpicker/RingtoneFactory.java
deleted file mode 100644
index cb41eabfa87a..000000000000
--- a/packages/SoundPicker2/src/com/android/soundpicker/RingtoneFactory.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2023 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.soundpicker;
-
-import android.content.Context;
-import android.media.AudioAttributes;
-import android.media.Ringtone;
-import android.net.Uri;
-
-import dagger.hilt.android.qualifiers.ApplicationContext;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-/**
- * A factory class used to create {@link Ringtone}.
- */
-@Singleton
-public class RingtoneFactory {
-
- private final Context mApplicationContext;
-
- @Inject
- RingtoneFactory(@ApplicationContext Context applicationContext) {
- mApplicationContext = applicationContext;
- }
-
- /**
- * Returns a {@link Ringtone} built from the provided URI and audio attributes flags.
- *
- * @param uri The URI used to build the {@link Ringtone}.
- * @param audioAttributesFlags A combination of audio attribute flags that affect the volume
- * and settings when playing the ringtone.
- * @return the built {@link Ringtone}.
- */
- public Ringtone create(Uri uri, int audioAttributesFlags) {
- AudioAttributes audioAttributes = new AudioAttributes.Builder()
- .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
- .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
- .setFlags(audioAttributesFlags)
- .build();
- // TODO: We are currently only using MEDIA_SOUND for enabledMedia. This will change once we
- // start playing sound and/or vibration.
- return new Ringtone.Builder(mApplicationContext, Ringtone.MEDIA_SOUND, audioAttributes)
- .setUri(uri)
- .build();
- }
-}
diff --git a/packages/SoundPicker2/src/com/android/soundpicker/RingtoneListHandler.java b/packages/SoundPicker2/src/com/android/soundpicker/RingtoneListHandler.java
deleted file mode 100644
index bb38e0e2ecaa..000000000000
--- a/packages/SoundPicker2/src/com/android/soundpicker/RingtoneListHandler.java
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Copyright (C) 2023 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.soundpicker;
-
-import static java.util.Objects.requireNonNull;
-
-import android.annotation.Nullable;
-import android.database.Cursor;
-import android.media.RingtoneManager;
-import android.net.Uri;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-
-import javax.inject.Inject;
-
-/**
- * Handles ringtone list state and actions. This includes keeping track of the selected item,
- * ringtone manager cursor and added items to the list.
- */
-public class RingtoneListHandler {
-
- // TODO: We're using an empty URI instead of null, because null URIs still produce a sound,
- // while empty ones don't (Potentially this might be due to empty URIs being perceived as
- // malformed ones). We will switch to using the official silent URIs (SOUND_OFF, VIBRATION_OFF)
- // once they become available.
- static final Uri SILENT_URI = Uri.EMPTY;
- static final int ITEM_POSITION_UNKNOWN = -1;
-
- private static final String TAG = "RingtoneListHandler";
-
- /** The position in the list of the 'Silent' item. */
- private int mSilentItemPosition = ITEM_POSITION_UNKNOWN;
- /** The position in the list of the 'Default' item. */
- private int mDefaultItemPosition = ITEM_POSITION_UNKNOWN;
- /** The number of fixed items in the list. */
- private int mFixedItemCount;
- /**
- * Stable ID for the ringtone that is currently selected (may be -1 if no ringtone is selected).
- */
- private long mSelectedItemId = -1;
- private int mSelectedItemPosition = ITEM_POSITION_UNKNOWN;
-
- private RingtoneManager mRingtoneManager;
- private Config mRingtoneListConfig;
- private Cursor mRingtoneCursor;
-
- /**
- * Holds immutable info on the ringtone list that is displayed.
- */
- static final class Config {
- /**
- * Whether this list has the 'Default' item.
- */
- public final boolean hasDefaultItem;
- /**
- * The Uri to play when the 'Default' item is clicked.
- */
- public final Uri uriForDefaultItem;
- /**
- * Whether this list has the 'Silent' item.
- */
- public final boolean hasSilentItem;
- /**
- * The initially selected uri in the list.
- */
- public final Uri initialSelectedUri;
-
- Config(boolean hasDefaultItem, Uri uriForDefaultItem, boolean hasSilentItem,
- Uri initialSelectedUri) {
- this.hasDefaultItem = hasDefaultItem;
- this.uriForDefaultItem = uriForDefaultItem;
- this.hasSilentItem = hasSilentItem;
- this.initialSelectedUri = initialSelectedUri;
- }
- }
-
- @Inject
- RingtoneListHandler() {
- }
-
- void init(@NonNull Config ringtoneListConfig,
- @NonNull RingtoneManager ringtoneManager, @NonNull Cursor ringtoneCursor) {
- mRingtoneManager = requireNonNull(ringtoneManager);
- mRingtoneListConfig = requireNonNull(ringtoneListConfig);
- mRingtoneCursor = requireNonNull(ringtoneCursor);
- }
-
- Config getRingtoneListConfig() {
- return mRingtoneListConfig;
- }
-
- Cursor getRingtoneCursor() {
- requireInitCalled();
- return mRingtoneCursor;
- }
-
- Uri getRingtoneUri(int position) {
- if (position < 0) {
- Log.w(TAG, "Selected item position is unknown.");
- // When the selected item is ITEM_POSITION_UNKNOWN, it is not the case we expected.
- // We return SILENT_URI for this case.
- return SILENT_URI;
- } else if (position == mDefaultItemPosition) {
- // Use the default Uri that they originally gave us.
- return mRingtoneListConfig.uriForDefaultItem;
- } else if (position == mSilentItemPosition) {
- // Use SILENT_URI for the 'Silent' item.
- return SILENT_URI;
- } else {
- requireInitCalled();
- return mRingtoneManager.getRingtoneUri(mapListPositionToRingtonePosition(position));
- }
- }
-
- int getRingtonePosition(Uri uri) {
- requireInitCalled();
- return mapRingtonePositionToListPosition(mRingtoneManager.getRingtonePosition(uri));
- }
-
- void resetFixedItems() {
- mFixedItemCount = 0;
- mDefaultItemPosition = ITEM_POSITION_UNKNOWN;
- mSilentItemPosition = ITEM_POSITION_UNKNOWN;
- }
-
- int addDefaultItem() {
- if (mDefaultItemPosition < 0) {
- mDefaultItemPosition = addFixedItem();
- }
- return mDefaultItemPosition;
- }
-
- int getDefaultItemPosition() {
- return mDefaultItemPosition;
- }
-
- int addSilentItem() {
- if (mSilentItemPosition < 0) {
- mSilentItemPosition = addFixedItem();
- }
- return mSilentItemPosition;
- }
-
- public int getSilentItemPosition() {
- return mSilentItemPosition;
- }
-
- int getSelectedItemPosition() {
- return mSelectedItemPosition;
- }
-
- void setSelectedItemPosition(int selectedItemPosition) {
- mSelectedItemPosition = selectedItemPosition;
- }
-
- void setSelectedItemId(long selectedItemId) {
- mSelectedItemId = selectedItemId;
- }
-
- long getSelectedItemId() {
- return mSelectedItemId;
- }
-
- @Nullable
- Uri getSelectedRingtoneUri() {
- return getRingtoneUri(mSelectedItemPosition);
- }
-
- /**
- * Maps the item position in the list, to its equivalent position in the RingtoneManager.
- *
- * @param itemPosition the position of item in the list.
- * @return position of the item in the RingtoneManager.
- */
- private int mapListPositionToRingtonePosition(int itemPosition) {
- // If the manager position is less than add items, then return that.
- if (itemPosition < mFixedItemCount) return itemPosition;
-
- return itemPosition - mFixedItemCount;
- }
-
- /**
- * Maps the item position in the RingtoneManager, to its equivalent position in the list.
- *
- * @param itemPosition the position of the item in the RingtoneManager.
- * @return position of the item in the list.
- */
- private int mapRingtonePositionToListPosition(int itemPosition) {
- // If the manager position is less than add items, then return that.
- if (itemPosition < 0) return itemPosition;
-
- return itemPosition + mFixedItemCount;
- }
-
- /**
- * Increments the number of added fixed items and returns the index of the newest added item.
- * @return index of the newest added fixed item.
- */
- private int addFixedItem() {
- return mFixedItemCount++;
- }
-
- private void requireInitCalled() {
- requireNonNull(mRingtoneManager);
- requireNonNull(mRingtoneCursor);
- }
-}
diff --git a/packages/SoundPicker2/src/com/android/soundpicker/RingtoneListViewAdapter.java b/packages/SoundPicker2/src/com/android/soundpicker/RingtoneListViewAdapter.java
deleted file mode 100644
index 4ca8943b5fd4..000000000000
--- a/packages/SoundPicker2/src/com/android/soundpicker/RingtoneListViewAdapter.java
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Copyright (C) 2023 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.soundpicker;
-
-import static com.android.internal.widget.RecyclerView.NO_ID;
-
-import android.database.Cursor;
-import android.graphics.drawable.Drawable;
-import android.media.RingtoneManager;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.CheckedTextView;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import androidx.annotation.StringRes;
-import androidx.recyclerview.widget.RecyclerView;
-
-import org.jetbrains.annotations.NotNull;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * The adapter presents a list of ringtones which may include fixed item in the list and an action
- * button at the end.
- *
- * The adapter handles three different types of items:
- * <ul>
- * <li>FIXED: Fixed items are items added to the top of the list. These items can not be modified
- * and their position will never change.
- * <li>DYNAMIC: Dynamic items are items from the ringtone manager. These items can be modified
- * and their position can change.
- * <li>FOOTER: A footer item is an added button to the end of the list. This item can be clicked
- * but not selected and its position will never change.
- * </ul>
- */
-final class RingtoneListViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
-
- private static final int VIEW_TYPE_FIXED_ITEM = 0;
- private static final int VIEW_TYPE_DYNAMIC_ITEM = 1;
- private static final int VIEW_TYPE_ADD_RINGTONE_ITEM = 2;
- private final Cursor mCursor;
- private final List<Integer> mFixedItemTitles;
- private final Callbacks mCallbacks;
- private final int mRowIDColumn;
- private int mSelectedItem = -1;
- @StringRes private Integer mAddRingtoneItemTitle;
-
- /** Provides callbacks for the adapter. */
- interface Callbacks {
- void onRingtoneSelected(int position);
- void onAddRingtoneSelected();
- boolean isWorkRingtone(int position);
- Drawable getWorkIconDrawable();
- }
-
- RingtoneListViewAdapter(Cursor cursor,
- Callbacks callbacks) {
- mCursor = cursor;
- mCallbacks = callbacks;
- mFixedItemTitles = new ArrayList<>();
- mRowIDColumn = mCursor != null ? mCursor.getColumnIndex("_id") : -1;
- setHasStableIds(true);
- }
-
- void setSelectedItem(int position) {
- notifyItemChanged(mSelectedItem);
- mSelectedItem = position;
- notifyItemChanged(mSelectedItem);
- }
-
- /**
- * Adds title to the fixed items list and returns the index of the newest added item.
- * @param textResId the title to add to the fixed items list.
- * @return The index of the newest added item in the fixed items list.
- */
- int addTitleForFixedItem(@StringRes int textResId) {
- mFixedItemTitles.add(textResId);
- notifyItemInserted(mFixedItemTitles.size() - 1);
- return mFixedItemTitles.size() - 1;
- }
-
- void addTitleForAddRingtoneItem(@StringRes int textResId) {
- mAddRingtoneItemTitle = textResId;
- notifyItemInserted(getItemCount() - 1);
- }
-
- @NotNull
- @Override
- public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
- LayoutInflater inflater = LayoutInflater.from(parent.getContext());
-
- if (viewType == VIEW_TYPE_FIXED_ITEM) {
- View fixedItemView = inflater.inflate(
- com.android.internal.R.layout.select_dialog_singlechoice_material, parent,
- false);
-
- return new FixedItemViewHolder(fixedItemView, mCallbacks);
- }
-
- if (viewType == VIEW_TYPE_ADD_RINGTONE_ITEM) {
- View addRingtoneItemView = inflater.inflate(R.layout.add_new_sound_item, parent, false);
-
- return new AddRingtoneItemViewHolder(addRingtoneItemView,
- mCallbacks);
- }
-
- View view = inflater.inflate(R.layout.radio_with_work_badge, parent, false);
-
- return new DynamicItemViewHolder(view, mCallbacks);
- }
-
- @Override
- public void onBindViewHolder(@NotNull RecyclerView.ViewHolder holder, int position) {
- if (holder instanceof FixedItemViewHolder) {
- FixedItemViewHolder viewHolder = (FixedItemViewHolder) holder;
-
- viewHolder.onBind(mFixedItemTitles.get(position),
- /* isChecked= */ position == mSelectedItem);
- return;
- }
- if (holder instanceof AddRingtoneItemViewHolder) {
- AddRingtoneItemViewHolder viewHolder = (AddRingtoneItemViewHolder) holder;
-
- viewHolder.onBind(mAddRingtoneItemTitle);
- return;
- }
-
- if (!(holder instanceof DynamicItemViewHolder)) {
- throw new IllegalArgumentException("holder type is not supported");
- }
-
- DynamicItemViewHolder viewHolder = (DynamicItemViewHolder) holder;
- int pos = position - mFixedItemTitles.size();
- if (!mCursor.moveToPosition(pos)) {
- throw new IllegalStateException("Could not move cursor to position: " + pos);
- }
-
- Drawable workIcon = (mCallbacks != null)
- && mCallbacks.isWorkRingtone(position)
- ? mCallbacks.getWorkIconDrawable() : null;
-
- viewHolder.onBind(mCursor.getString(RingtoneManager.TITLE_COLUMN_INDEX),
- /* isChecked= */ position == mSelectedItem, workIcon);
- }
-
- @Override
- public int getItemViewType(int position) {
- if (!mFixedItemTitles.isEmpty() && position < mFixedItemTitles.size()) {
- return VIEW_TYPE_FIXED_ITEM;
- }
- if (mAddRingtoneItemTitle != null && position == getItemCount() - 1) {
- return VIEW_TYPE_ADD_RINGTONE_ITEM;
- }
-
- return VIEW_TYPE_DYNAMIC_ITEM;
- }
-
- @Override
- public int getItemCount() {
- int itemCount = mFixedItemTitles.size() + mCursor.getCount();
-
- if (mAddRingtoneItemTitle != null) {
- itemCount++;
- }
-
- return itemCount;
- }
-
- @Override
- public long getItemId(int position) {
- int itemViewType = getItemViewType(position);
- if (itemViewType == VIEW_TYPE_FIXED_ITEM) {
- // Since the item is a fixed item, then we can use the position as a stable ID
- // since the order of the fixed items should never change.
- return position;
- }
- if (itemViewType == VIEW_TYPE_DYNAMIC_ITEM && mCursor != null
- && mCursor.moveToPosition(position - mFixedItemTitles.size())
- && mRowIDColumn != -1) {
- return mCursor.getLong(mRowIDColumn) + mFixedItemTitles.size();
- }
-
- // The position is either invalid or the item is the add ringtone item view, so no stable
- // ID is returned. Add ringtone item view cannot be selected and only include an action
- // buttons.
- return NO_ID;
- }
-
- private static class DynamicItemViewHolder extends RecyclerView.ViewHolder {
- private final CheckedTextView mTitleTextView;
- private final ImageView mWorkIcon;
-
- DynamicItemViewHolder(View itemView, Callbacks listener) {
- super(itemView);
-
- mTitleTextView = itemView.requireViewById(R.id.checked_text_view);
- mWorkIcon = itemView.requireViewById(R.id.work_icon);
- itemView.setOnClickListener(v -> listener.onRingtoneSelected(this.getLayoutPosition()));
- }
-
- void onBind(String title, boolean isChecked, Drawable workIcon) {
- mTitleTextView.setText(title);
- mTitleTextView.setChecked(isChecked);
-
- if (workIcon == null) {
- mWorkIcon.setVisibility(View.GONE);
- } else {
- mWorkIcon.setImageDrawable(workIcon);
- mWorkIcon.setVisibility(View.VISIBLE);
- }
- }
- }
-
- private static class FixedItemViewHolder extends RecyclerView.ViewHolder {
- private final CheckedTextView mTitleTextView;
-
- FixedItemViewHolder(View itemView, Callbacks listener) {
- super(itemView);
-
- mTitleTextView = (CheckedTextView) itemView;
- itemView.setOnClickListener(v -> listener.onRingtoneSelected(this.getLayoutPosition()));
- }
-
- void onBind(@StringRes int title, boolean isChecked) {
- Objects.requireNonNull(mTitleTextView);
-
- mTitleTextView.setText(title);
- mTitleTextView.setChecked(isChecked);
- }
- }
-
- private static class AddRingtoneItemViewHolder extends RecyclerView.ViewHolder {
- private final TextView mTitleTextView;
-
- AddRingtoneItemViewHolder(View itemView, Callbacks listener) {
- super(itemView);
-
- mTitleTextView = itemView.requireViewById(R.id.add_new_sound_text);
- itemView.setOnClickListener(v -> listener.onAddRingtoneSelected());
- }
-
- void onBind(@StringRes int title) {
- mTitleTextView.setText(title);
- }
- }
-}
diff --git a/packages/SoundPicker2/src/com/android/soundpicker/RingtoneManagerFactory.java b/packages/SoundPicker2/src/com/android/soundpicker/RingtoneManagerFactory.java
deleted file mode 100644
index f08eb24ec20d..000000000000
--- a/packages/SoundPicker2/src/com/android/soundpicker/RingtoneManagerFactory.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2023 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.soundpicker;
-
-import android.content.Context;
-import android.media.RingtoneManager;
-
-import dagger.hilt.android.qualifiers.ApplicationContext;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-/**
- * A factory class used to create {@link RingtoneManager}.
- */
-@Singleton
-public class RingtoneManagerFactory {
-
- private final Context mApplicationContext;
-
- @Inject
- RingtoneManagerFactory(@ApplicationContext Context applicationContext) {
- mApplicationContext = applicationContext;
- }
-
- /**
- * Creates a new {@link RingtoneManager} and returns it.
- *
- * @return a {@link RingtoneManager}
- */
- public RingtoneManager create() {
- return new RingtoneManager(mApplicationContext, /* includeParentRingtones */ true);
- }
-}
-
diff --git a/packages/SoundPicker2/src/com/android/soundpicker/RingtoneOverlayService.java b/packages/SoundPicker2/src/com/android/soundpicker/RingtoneOverlayService.java
deleted file mode 100644
index b94ebebd825b..000000000000
--- a/packages/SoundPicker2/src/com/android/soundpicker/RingtoneOverlayService.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2018 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.soundpicker;
-
-import android.app.Service;
-import android.content.Intent;
-import android.media.RingtoneManager;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Environment;
-import android.os.FileUtils;
-import android.os.IBinder;
-import android.provider.MediaStore;
-import android.provider.Settings.System;
-import android.util.Log;
-
-import androidx.annotation.IdRes;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * Service to copy and set customization of default sounds
- */
-public class RingtoneOverlayService extends Service {
- private static final String TAG = "RingtoneOverlayService";
- private static final boolean DEBUG = false;
-
- @Override
- public int onStartCommand(@Nullable final Intent intent, final int flags, final int startId) {
- AsyncTask.execute(() -> {
- updateRingtones();
- stopSelf();
- });
-
- // Try again later if we are killed before we finish.
- return Service.START_REDELIVER_INTENT;
- }
-
- @Override
- public IBinder onBind(@Nullable final Intent intent) {
- return null;
- }
-
- private void updateRingtones() {
- copyResourceAndSetAsSound(R.raw.default_ringtone,
- System.RINGTONE, Environment.DIRECTORY_RINGTONES);
- copyResourceAndSetAsSound(R.raw.default_notification_sound,
- System.NOTIFICATION_SOUND, Environment.DIRECTORY_NOTIFICATIONS);
- copyResourceAndSetAsSound(R.raw.default_alarm_alert,
- System.ALARM_ALERT, Environment.DIRECTORY_ALARMS);
- }
-
- /* If the resource contains any data, copy a resource to the file system, scan it, and set the
- * file URI as the default for a sound. */
- private void copyResourceAndSetAsSound(@IdRes final int id, @NonNull final String name,
- @NonNull final String subPath) {
- final File destDir = Environment.getExternalStoragePublicDirectory(subPath);
- if (!destDir.exists() && !destDir.mkdirs()) {
- Log.e(TAG, "can't create " + destDir.getAbsolutePath());
- return;
- }
-
- final File dest = new File(destDir, "default_" + name + ".ogg");
- try (
- InputStream is = getResources().openRawResource(id);
- FileOutputStream os = new FileOutputStream(dest);
- ) {
- if (is.available() > 0) {
- FileUtils.copy(is, os);
- final Uri uri = scanFile(dest);
- if (uri != null) {
- set(name, uri);
- }
- } else {
- // TODO Shall we remove any former copied resource in this case and unset
- // the defaults if we use this event a second time to clear the data?
- if (DEBUG) Log.d(TAG, "Resource for " + name + " has no overlay");
- }
- } catch (IOException e) {
- Log.e(TAG, "Unable to open resource for " + name + ": " + e);
- }
- }
-
- private Uri scanFile(@NonNull final File file) {
- return MediaStore.scanFile(getContentResolver(), file);
- }
-
- private void set(@NonNull final String name, @NonNull final Uri uri) {
- final Uri settingUri = System.getUriFor(name);
- RingtoneManager.setActualDefaultRingtoneUri(this,
- RingtoneManager.getDefaultType(settingUri), uri);
- System.putInt(getContentResolver(), name + "_set", 1);
- }
-}
diff --git a/packages/SoundPicker2/src/com/android/soundpicker/RingtonePickerActivity.java b/packages/SoundPicker2/src/com/android/soundpicker/RingtonePickerActivity.java
deleted file mode 100644
index 90a14f9717db..000000000000
--- a/packages/SoundPicker2/src/com/android/soundpicker/RingtonePickerActivity.java
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Copyright (C) 2007 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.soundpicker;
-
-import android.content.Intent;
-import android.media.RingtoneManager;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.UserHandle;
-import android.util.Log;
-
-import androidx.appcompat.app.AppCompatActivity;
-import androidx.fragment.app.Fragment;
-import androidx.fragment.app.FragmentTransaction;
-import androidx.lifecycle.ViewModelProvider;
-
-import dagger.hilt.android.AndroidEntryPoint;
-
-/**
- * The {@link RingtonePickerActivity} allows the user to choose one from all of the
- * available ringtones. The chosen ringtone's URI will be persisted as a string.
- *
- * @see RingtoneManager#ACTION_RINGTONE_PICKER
- */
-@AndroidEntryPoint(AppCompatActivity.class)
-public final class RingtonePickerActivity extends Hilt_RingtonePickerActivity {
-
- private static final String TAG = "RingtonePickerActivity";
- // TODO: Use the extra keys from RingtoneManager once they're added.
- private static final String EXTRA_RINGTONE_PICKER_CATEGORY = "EXTRA_RINGTONE_PICKER_CATEGORY";
- private static final String EXTRA_VIBRATION_SHOW_DEFAULT = "EXTRA_VIBRATION_SHOW_DEFAULT";
- private static final String EXTRA_VIBRATION_DEFAULT_URI = "EXTRA_VIBRATION_DEFAULT_URI";
- private static final String EXTRA_VIBRATION_SHOW_SILENT = "EXTRA_VIBRATION_SHOW_SILENT";
- private static final String EXTRA_VIBRATION_EXISTING_URI = "EXTRA_VIBRATION_EXISTING_URI";
- private static final boolean RINGTONE_PICKER_CATEGORY_FEATURE_ENABLED = false;
-
- private RingtonePickerViewModel mRingtonePickerViewModel;
- private int mAttributesFlags;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_ringtone_picker);
-
- mRingtonePickerViewModel = new ViewModelProvider(this).get(RingtonePickerViewModel.class);
-
- Intent intent = getIntent();
- /**
- * Id of the user to which the ringtone picker should list the ringtones
- */
- int pickerUserId = UserHandle.myUserId();
-
- // Get the types of ringtones to show
- int ringtoneType = intent.getIntExtra(RingtoneManager.EXTRA_RINGTONE_TYPE,
- RingtonePickerViewModel.RINGTONE_TYPE_UNKNOWN);
-
- // AudioAttributes flags
- mAttributesFlags |= intent.getIntExtra(
- RingtoneManager.EXTRA_RINGTONE_AUDIO_ATTRIBUTES_FLAGS,
- 0 /*defaultValue == no flags*/);
-
- boolean showOkCancelButtons = getResources().getBoolean(R.bool.config_showOkCancelButtons);
-
- String title = intent.getStringExtra(RingtoneManager.EXTRA_RINGTONE_TITLE);
- if (title == null) {
- title = getString(RingtonePickerViewModel.getTitleByType(ringtoneType));
- }
- String ringtonePickerCategory = intent.getStringExtra(EXTRA_RINGTONE_PICKER_CATEGORY);
- RingtonePickerViewModel.PickerType pickerType = mapCategoryToPickerType(
- ringtonePickerCategory);
-
- RingtoneListHandler.Config soundListConfig = getSoundListConfig(pickerType, intent,
- ringtoneType);
- RingtoneListHandler.Config vibrationListConfig = getVibrationListConfig(pickerType, intent);
-
- RingtonePickerViewModel.Config pickerConfig =
- new RingtonePickerViewModel.Config(title, pickerUserId, ringtoneType,
- showOkCancelButtons, mAttributesFlags, pickerType);
-
- mRingtonePickerViewModel.init(pickerConfig, soundListConfig, vibrationListConfig);
-
- if (savedInstanceState == null) {
- TabbedDialogFragment dialogFragment = new TabbedDialogFragment();
-
- FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
- Fragment prev = getSupportFragmentManager().findFragmentByTag(TabbedDialogFragment.TAG);
- if (prev != null) {
- ft.remove(prev);
- }
- ft.addToBackStack(null);
- dialogFragment.show(ft, TabbedDialogFragment.TAG);
- }
-
- // The volume keys will control the stream that we are choosing a ringtone for
- setVolumeControlStream(mRingtonePickerViewModel.getRingtoneStreamType());
- }
-
- private RingtoneListHandler.Config getSoundListConfig(
- RingtonePickerViewModel.PickerType pickerType, Intent intent, int ringtoneType) {
- if (pickerType != RingtonePickerViewModel.PickerType.SOUND_PICKER
- && pickerType != RingtonePickerViewModel.PickerType.RINGTONE_PICKER) {
- // This ringtone picker does not require a sound picker.
- return null;
- }
-
- // Get whether to show the 'Default' sound item, and the URI to play when it's clicked
- boolean hasDefaultSoundItem =
- intent.getBooleanExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, true);
-
- // The Uri to play when the 'Default' sound item is clicked.
- Uri uriForDefaultSoundItem =
- intent.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_DEFAULT_URI);
- if (uriForDefaultSoundItem == null) {
- uriForDefaultSoundItem = RingtonePickerViewModel.getDefaultItemUriByType(ringtoneType);
- }
-
- // Get whether this list has the 'Silent' sound item.
- boolean hasSilentSoundItem =
- intent.getBooleanExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, true);
-
- // AudioAttributes flags
- mAttributesFlags |= intent.getIntExtra(
- RingtoneManager.EXTRA_RINGTONE_AUDIO_ATTRIBUTES_FLAGS,
- 0 /*defaultValue == no flags*/);
-
- // Get the sound URI whose list item should have a checkmark
- Uri existingSoundUri = intent
- .getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI);
-
- return new RingtoneListHandler.Config(hasDefaultSoundItem,
- uriForDefaultSoundItem, hasSilentSoundItem, existingSoundUri);
- }
-
- private RingtoneListHandler.Config getVibrationListConfig(
- RingtonePickerViewModel.PickerType pickerType, Intent intent) {
- if (pickerType != RingtonePickerViewModel.PickerType.VIBRATION_PICKER
- && pickerType != RingtonePickerViewModel.PickerType.RINGTONE_PICKER) {
- // This ringtone picker does not require a vibration picker.
- return null;
- }
-
- // Get whether to show the 'Default' vibration item, and the URI to play when it's clicked
- boolean hasDefaultVibrationItem =
- intent.getBooleanExtra(EXTRA_VIBRATION_SHOW_DEFAULT, false);
-
- // The Uri to play when the 'Default' vibration item is clicked.
- Uri uriForDefaultVibrationItem = intent.getParcelableExtra(EXTRA_VIBRATION_DEFAULT_URI);
-
- // Get whether this list has the 'Silent' vibration item.
- boolean hasSilentVibrationItem =
- intent.getBooleanExtra(EXTRA_VIBRATION_SHOW_SILENT, true);
-
- // Get the vibration URI whose list item should have a checkmark
- Uri existingVibrationUri = intent.getParcelableExtra(EXTRA_VIBRATION_EXISTING_URI);
-
- return new RingtoneListHandler.Config(
- hasDefaultVibrationItem, uriForDefaultVibrationItem, hasSilentVibrationItem,
- existingVibrationUri);
- }
-
- @Override
- public void onDestroy() {
- mRingtonePickerViewModel.cancelPendingAsyncTasks();
- super.onDestroy();
- }
-
- @Override
- protected void onStop() {
- super.onStop();
- mRingtonePickerViewModel.onStop(isChangingConfigurations());
- }
-
- @Override
- protected void onPause() {
- super.onPause();
- mRingtonePickerViewModel.onPause(isChangingConfigurations());
- }
-
- /**
- * Maps the ringtone picker category to the appropriate PickerType.
- * If the category is null or the feature is still not released, then it defaults to sound
- * picker.
- *
- * @param category the ringtone picker category.
- * @return the corresponding picker type.
- */
- private static RingtonePickerViewModel.PickerType mapCategoryToPickerType(String category) {
- if (category == null || !RINGTONE_PICKER_CATEGORY_FEATURE_ENABLED) {
- return RingtonePickerViewModel.PickerType.SOUND_PICKER;
- }
-
- switch (category) {
- case "android.intent.category.RINGTONE_PICKER_RINGTONE":
- return RingtonePickerViewModel.PickerType.RINGTONE_PICKER;
- case "android.intent.category.RINGTONE_PICKER_SOUND":
- return RingtonePickerViewModel.PickerType.SOUND_PICKER;
- case "android.intent.category.RINGTONE_PICKER_VIBRATION":
- return RingtonePickerViewModel.PickerType.VIBRATION_PICKER;
- default:
- Log.w(TAG, "Unrecognized category: " + category + ". Defaulting to sound picker.");
- return RingtonePickerViewModel.PickerType.SOUND_PICKER;
- }
- }
-}
diff --git a/packages/SoundPicker2/src/com/android/soundpicker/RingtonePickerApplication.java b/packages/SoundPicker2/src/com/android/soundpicker/RingtonePickerApplication.java
deleted file mode 100644
index 48fd4fe2f15e..000000000000
--- a/packages/SoundPicker2/src/com/android/soundpicker/RingtonePickerApplication.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2023 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.soundpicker;
-
-import android.app.Application;
-
-import dagger.hilt.android.HiltAndroidApp;
-
-/**
- * The main application class for the project.
- */
-@HiltAndroidApp(Application.class)
-public class RingtonePickerApplication extends Hilt_RingtonePickerApplication {
-}
diff --git a/packages/SoundPicker2/src/com/android/soundpicker/RingtonePickerViewModel.java b/packages/SoundPicker2/src/com/android/soundpicker/RingtonePickerViewModel.java
deleted file mode 100644
index 2c0971121ccd..000000000000
--- a/packages/SoundPicker2/src/com/android/soundpicker/RingtonePickerViewModel.java
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * Copyright (C) 2023 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.soundpicker;
-
-import static java.util.Objects.requireNonNull;
-
-import android.annotation.Nullable;
-import android.annotation.StringRes;
-import android.media.Ringtone;
-import android.media.RingtoneManager;
-import android.net.Uri;
-import android.provider.Settings;
-
-import androidx.annotation.NonNull;
-import androidx.lifecycle.ViewModel;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.ListeningExecutorService;
-
-import dagger.hilt.android.lifecycle.HiltViewModel;
-
-import java.io.IOException;
-import java.util.concurrent.Executor;
-
-import javax.inject.Inject;
-
-/**
- * A view model which holds immutable info about the picker state and means to retrieve and play
- * currently selected ringtones.
- */
-@HiltViewModel
-public final class RingtonePickerViewModel extends ViewModel {
-
- static final int RINGTONE_TYPE_UNKNOWN = -1;
-
- /**
- * Keep the currently playing ringtone around when changing orientation, so that it
- * can be stopped later, after the activity is recreated.
- */
- @VisibleForTesting
- static Ringtone sPlayingRingtone;
-
- private static final String TAG = "RingtonePickerViewModel";
-
- private final RingtoneManagerFactory mRingtoneManagerFactory;
- private final RingtoneFactory mRingtoneFactory;
- private final RingtoneListHandler mSoundListHandler;
- private final RingtoneListHandler mVibrationListHandler;
- private final ListeningExecutorService mListeningExecutorService;
-
- private RingtoneManager mRingtoneManager;
-
- /**
- * The ringtone that's currently playing.
- */
- private Ringtone mCurrentRingtone;
-
- private Config mPickerConfig;
-
- private ListenableFuture<Uri> mAddCustomRingtoneFuture;
-
- public enum PickerType {
- RINGTONE_PICKER,
- SOUND_PICKER,
- VIBRATION_PICKER
- }
-
- /**
- * Holds immutable info on the picker that should be displayed.
- */
- static final class Config {
- public final String title;
- /**
- * Id of the user to which the ringtone picker should list the ringtones.
- */
- public final int userId;
- /**
- * Ringtone type.
- */
- public final int ringtoneType;
- /**
- * AudioAttributes flags.
- */
- public final int audioAttributesFlags;
- /**
- * In the buttonless (watch-only) version we don't show the OK/Cancel buttons.
- */
- public final boolean showOkCancelButtons;
-
- public final PickerType mPickerType;
-
- Config(String title, int userId, int ringtoneType, boolean showOkCancelButtons,
- int audioAttributesFlags, PickerType pickerType) {
- this.title = title;
- this.userId = userId;
- this.ringtoneType = ringtoneType;
- this.showOkCancelButtons = showOkCancelButtons;
- this.audioAttributesFlags = audioAttributesFlags;
- this.mPickerType = pickerType;
- }
- }
-
- @Inject
- RingtonePickerViewModel(RingtoneManagerFactory ringtoneManagerFactory,
- RingtoneFactory ringtoneFactory,
- ListeningExecutorServiceFactory listeningExecutorServiceFactory,
- RingtoneListHandler soundListHandler,
- RingtoneListHandler vibrationListHandler) {
- mRingtoneManagerFactory = ringtoneManagerFactory;
- mRingtoneFactory = ringtoneFactory;
- mListeningExecutorService = listeningExecutorServiceFactory.createSingleThreadExecutor();
- mSoundListHandler = soundListHandler;
- mVibrationListHandler = vibrationListHandler;
- }
-
- @StringRes
- static int getTitleByType(int ringtoneType) {
- switch (ringtoneType) {
- case RingtoneManager.TYPE_ALARM:
- return com.android.internal.R.string.ringtone_picker_title_alarm;
- case RingtoneManager.TYPE_NOTIFICATION:
- return com.android.internal.R.string.ringtone_picker_title_notification;
- default:
- return com.android.internal.R.string.ringtone_picker_title;
- }
- }
-
- static Uri getDefaultItemUriByType(int ringtoneType) {
- switch (ringtoneType) {
- case RingtoneManager.TYPE_ALARM:
- return Settings.System.DEFAULT_ALARM_ALERT_URI;
- case RingtoneManager.TYPE_NOTIFICATION:
- return Settings.System.DEFAULT_NOTIFICATION_URI;
- default:
- return Settings.System.DEFAULT_RINGTONE_URI;
- }
- }
-
- @StringRes
- static int getAddNewItemTextByType(int ringtoneType) {
- switch (ringtoneType) {
- case RingtoneManager.TYPE_ALARM:
- return R.string.add_alarm_text;
- case RingtoneManager.TYPE_NOTIFICATION:
- return R.string.add_notification_text;
- default:
- return R.string.add_ringtone_text;
- }
- }
-
- @StringRes
- static int getDefaultRingtoneItemTextByType(int ringtoneType) {
- switch (ringtoneType) {
- case RingtoneManager.TYPE_ALARM:
- return R.string.alarm_sound_default;
- case RingtoneManager.TYPE_NOTIFICATION:
- return R.string.notification_sound_default;
- default:
- return R.string.ringtone_default;
- }
- }
-
- void init(@NonNull Config pickerConfig,
- RingtoneListHandler.Config soundListConfig,
- RingtoneListHandler.Config vibrationListConfig) {
- mRingtoneManager = mRingtoneManagerFactory.create();
- mPickerConfig = pickerConfig;
- if (mPickerConfig.ringtoneType != RINGTONE_TYPE_UNKNOWN) {
- mRingtoneManager.setType(mPickerConfig.ringtoneType);
- }
- if (soundListConfig != null) {
- mSoundListHandler.init(soundListConfig, mRingtoneManager,
- mRingtoneManager.getCursor());
- }
- if (vibrationListConfig != null) {
- // TODO: Switch to the vibration cursor, once the API is made available.
- mVibrationListHandler.init(vibrationListConfig, mRingtoneManager,
- mRingtoneManager.getCursor());
- }
- }
-
- /**
- * Re-initializes the view model which is required after updating any of the picker lists.
- * This could happen when adding a custom ringtone.
- */
- void reinit() {
- init(mPickerConfig, mSoundListHandler.getRingtoneListConfig(),
- mVibrationListHandler.getRingtoneListConfig());
- }
-
- @NonNull
- Config getPickerConfig() {
- requireInitCalled();
- return mPickerConfig;
- }
-
- @NonNull
- RingtoneListHandler getSoundListHandler() {
- return mSoundListHandler;
- }
-
- @NonNull
- RingtoneListHandler getVibrationListHandler() {
- return mVibrationListHandler;
- }
-
- /**
- * Combined the currently selected sound and vibration URIs and returns a unified URI. If the
- * picker does not show either sound or vibration, that portion of the URI will be null.
- *
- * Currently only the sound URI is returned, since we don't have the API to retrieve vibrations
- * yet.
- * @return Combined sound and vibration URI.
- */
- Uri getSelectedRingtoneUri() {
- // TODO: Combine sound and vibration URIs before returning.
- return mSoundListHandler.getSelectedRingtoneUri();
- }
-
- int getRingtoneStreamType() {
- requireInitCalled();
- return mRingtoneManager.inferStreamType();
- }
-
- void onPause(boolean isChangingConfigurations) {
- if (!isChangingConfigurations) {
- stopAnyPlayingRingtone();
- }
- }
-
- void onStop(boolean isChangingConfigurations) {
- if (isChangingConfigurations) {
- saveAnyPlayingRingtone();
- } else {
- stopAnyPlayingRingtone();
- }
- }
-
- /**
- * Plays a ringtone which is created using the currently selected sound and vibration URIs. If
- * this is a sound or vibration only picker, then the other portion of the URI will be empty
- * and should not affect the played ringtone.
- *
- * Currently, we only use the sound URI to create the ringtone, since we still don't have the
- * API to retrieve the available vibrations list.
- */
- void playRingtone() {
- requireInitCalled();
- stopAnyPlayingRingtone();
-
- mCurrentRingtone = mRingtoneFactory.create(getSelectedRingtoneUri(),
- mPickerConfig.audioAttributesFlags);
-
- if (mCurrentRingtone != null) {
- mCurrentRingtone.play();
- }
- }
-
- /**
- * Cancels all pending async tasks.
- */
- void cancelPendingAsyncTasks() {
- if (mAddCustomRingtoneFuture != null && !mAddCustomRingtoneFuture.isDone()) {
- mAddCustomRingtoneFuture.cancel(/* mayInterruptIfRunning= */ true);
- }
- }
-
- /**
- * Adds an audio file to the list of ringtones asynchronously.
- * Any previous async tasks are canceled before start the new one.
- *
- * @param uri Uri of the file to be added as ringtone. Must be a media file.
- * @param type The type of the ringtone to be added.
- * @param callback The callback to invoke when the task is completed.
- * @param executor The executor to run the callback on when the task completes.
- */
- void addSoundRingtoneAsync(Uri uri, int type, FutureCallback<Uri> callback, Executor executor) {
- // Cancel any currently running add ringtone tasks before starting a new one
- cancelPendingAsyncTasks();
- mAddCustomRingtoneFuture = mListeningExecutorService.submit(
- () -> addRingtone(uri, type));
- Futures.addCallback(mAddCustomRingtoneFuture, callback, executor);
- }
-
- /**
- * Adds an audio file to the list of ringtones.
- *
- * @param uri Uri of the file to be added as ringtone. Must be a media file.
- * @param type The type of the ringtone to be added.
- * @return The Uri of the installed ringtone, which may be the {@code uri} if it
- * is already in ringtone storage. Or null if it failed to add the audio file.
- */
- @Nullable
- private Uri addRingtone(Uri uri, int type) throws IOException {
- requireInitCalled();
- return mRingtoneManager.addCustomExternalRingtone(uri, type);
- }
-
- private void saveAnyPlayingRingtone() {
- if (mCurrentRingtone != null && mCurrentRingtone.isPlaying()) {
- sPlayingRingtone = mCurrentRingtone;
- }
- mCurrentRingtone = null;
- }
-
- private void stopAnyPlayingRingtone() {
- if (sPlayingRingtone != null && sPlayingRingtone.isPlaying()) {
- sPlayingRingtone.stop();
- }
- sPlayingRingtone = null;
-
- if (mCurrentRingtone != null && mCurrentRingtone.isPlaying()) {
- mCurrentRingtone.stop();
- }
- mCurrentRingtone = null;
- }
-
- private void requireInitCalled() {
- requireNonNull(mRingtoneManager);
- requireNonNull(mPickerConfig);
- }
-}
diff --git a/packages/SoundPicker2/src/com/android/soundpicker/RingtoneReceiver.java b/packages/SoundPicker2/src/com/android/soundpicker/RingtoneReceiver.java
deleted file mode 100644
index 6a349366e744..000000000000
--- a/packages/SoundPicker2/src/com/android/soundpicker/RingtoneReceiver.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2007 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.soundpicker;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-
-public class RingtoneReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- final String action = intent.getAction();
- if (Intent.ACTION_DEVICE_CUSTOMIZATION_READY.equals(action)) {
- initResourceRingtones(context);
- }
- }
-
- private void initResourceRingtones(Context context) {
- context.startService(
- new Intent(context, RingtoneOverlayService.class));
- }
-}
diff --git a/packages/SoundPicker2/src/com/android/soundpicker/SoundPickerFragment.java b/packages/SoundPicker2/src/com/android/soundpicker/SoundPickerFragment.java
deleted file mode 100644
index a37191f33668..000000000000
--- a/packages/SoundPicker2/src/com/android/soundpicker/SoundPickerFragment.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2023 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.soundpicker;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Environment;
-import android.util.Log;
-import android.view.View;
-import android.widget.Toast;
-
-import androidx.activity.result.ActivityResult;
-import androidx.activity.result.ActivityResultCallback;
-import androidx.activity.result.ActivityResultLauncher;
-import androidx.activity.result.contract.ActivityResultContracts;
-import androidx.core.content.ContextCompat;
-import androidx.lifecycle.ViewModelProvider;
-
-import com.google.common.util.concurrent.FutureCallback;
-
-import org.jetbrains.annotations.NotNull;
-
-/**
- * A fragment that displays a picker used to select sound or silent. It also includes the
- * ability to add custom sounds.
- */
-public class SoundPickerFragment extends BasePickerFragment {
-
- private static final String TAG = "SoundPickerFragment";
-
- private final FutureCallback<Uri> mAddCustomRingtoneCallback = new FutureCallback<>() {
- @Override
- public void onSuccess(Uri ringtoneUri) {
- requeryForAdapter();
- }
-
- @Override
- public void onFailure(Throwable throwable) {
- Log.e(TAG, "Failed to add custom ringtone.", throwable);
- // Ringtone was not added, display error Toast
- Toast.makeText(requireActivity().getApplicationContext(),
- R.string.unable_to_add_ringtone, Toast.LENGTH_SHORT).show();
- }
- };
-
- ActivityResultLauncher<Intent> mActivityResultLauncher = registerForActivityResult(
- new ActivityResultContracts.StartActivityForResult(),
- new ActivityResultCallback<ActivityResult>() {
- @Override
- public void onActivityResult(ActivityResult result) {
- if (result.getResultCode() == Activity.RESULT_OK) {
- // There are no request codes
- Intent data = result.getData();
- mRingtonePickerViewModel.addSoundRingtoneAsync(data.getData(),
- mPickerConfig.ringtoneType,
- mAddCustomRingtoneCallback,
- // Causes the callback to be executed on the main thread.
- ContextCompat.getMainExecutor(
- requireActivity().getApplicationContext()));
- }
- }
- });
-
- @Override
- public void onViewCreated(@NotNull View view, Bundle savedInstanceState) {
- mRingtonePickerViewModel = new ViewModelProvider(requireActivity()).get(
- RingtonePickerViewModel.class);
- super.onViewCreated(view, savedInstanceState);
- }
-
- @Override
- protected RingtoneListHandler getRingtoneListHandler() {
- return mRingtonePickerViewModel.getSoundListHandler();
- }
-
- @Override
- protected void addRingtoneAsync() {
- // The "Add new ringtone" item was clicked. Start a file picker intent to
- // select only audio files (MIME type "audio/*")
- final Intent chooseFile = getMediaFilePickerIntent();
- mActivityResultLauncher.launch(chooseFile);
- }
-
- @Override
- protected void addNewRingtoneItem() {
- // If external storage is available, add a button to install sounds from storage.
- if (resolvesMediaFilePicker()
- && Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
- mRingtoneListViewAdapter.addTitleForAddRingtoneItem(
- RingtonePickerViewModel.getAddNewItemTextByType(mPickerConfig.ringtoneType));
- }
- }
-
- private boolean resolvesMediaFilePicker() {
- return getMediaFilePickerIntent().resolveActivity(requireActivity().getPackageManager())
- != null;
- }
-
- private Intent getMediaFilePickerIntent() {
- final Intent chooseFile = new Intent(Intent.ACTION_GET_CONTENT);
- chooseFile.setType("audio/*");
- chooseFile.putExtra(Intent.EXTRA_MIME_TYPES,
- new String[]{"audio/*", "application/ogg"});
- return chooseFile;
- }
-}
diff --git a/packages/SoundPicker2/src/com/android/soundpicker/TabbedDialogFragment.java b/packages/SoundPicker2/src/com/android/soundpicker/TabbedDialogFragment.java
deleted file mode 100644
index 50ea9d7d3056..000000000000
--- a/packages/SoundPicker2/src/com/android/soundpicker/TabbedDialogFragment.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2023 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.soundpicker;
-
-import static android.app.Activity.RESULT_CANCELED;
-
-import android.app.Activity;
-import android.app.Dialog;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.media.RingtoneManager;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.appcompat.app.AlertDialog;
-import androidx.fragment.app.DialogFragment;
-import androidx.lifecycle.ViewModelProvider;
-import androidx.viewpager2.widget.ViewPager2;
-
-import com.google.android.material.tabs.TabLayout;
-import com.google.android.material.tabs.TabLayoutMediator;
-
-import dagger.hilt.android.AndroidEntryPoint;
-
-import org.jetbrains.annotations.NotNull;
-
-/**
- * A dialog fragment with a sound and/or vibration tab based on the picker type.
- * <ul>
- * <li> Ringtone Pickers will display both sound and vibration tabs.
- * <li> Sound Pickers will only display the sound tab.
- * <li> Vibration Pickers will only display the vibration tab.
- * </ul>
- */
-@AndroidEntryPoint(DialogFragment.class)
-public class TabbedDialogFragment extends Hilt_TabbedDialogFragment {
-
- static final String TAG = "TabbedDialogFragment";
-
- private RingtonePickerViewModel mRingtonePickerViewModel;
-
- private final ViewPager2.OnPageChangeCallback mOnPageChangeCallback =
- new ViewPager2.OnPageChangeCallback() {
- @Override
- public void onPageScrollStateChanged(int state) {
- super.onPageScrollStateChanged(state);
- if (state == ViewPager2.SCROLL_STATE_IDLE) {
- mRingtonePickerViewModel.onStop(/* isChangingConfigurations= */ false);
- }
- }
- };
-
- @Override
- public void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- mRingtonePickerViewModel = new ViewModelProvider(requireActivity()).get(
- RingtonePickerViewModel.class);
- }
-
- @NonNull
- @Override
- public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
- AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(requireActivity(),
- android.R.style.ThemeOverlay_Material_Dialog)
- .setTitle(mRingtonePickerViewModel.getPickerConfig().title);
- // Do not show OK/Cancel buttons in the buttonless (watch-only) version.
- if (mRingtonePickerViewModel.getPickerConfig().showOkCancelButtons) {
- dialogBuilder
- .setPositiveButton(getString(com.android.internal.R.string.ok),
- (dialog, whichButton) -> {
- setSuccessResultWithSelectedRingtone();
- requireActivity().finish();
- })
- .setNegativeButton(getString(com.android.internal.R.string.cancel),
- (dialog, whichButton) -> {
- requireActivity().setResult(RESULT_CANCELED);
- requireActivity().finish();
- });
- }
-
- View view = buildTabbedView(requireActivity().getLayoutInflater());
- dialogBuilder.setView(view);
-
- return dialogBuilder.create();
- }
-
- @Override
- public void onCancel(@NonNull @NotNull DialogInterface dialog) {
- super.onCancel(dialog);
- if (!requireActivity().isChangingConfigurations()) {
- requireActivity().finish();
- }
- }
-
- @Override
- public void onDismiss(@NonNull @NotNull DialogInterface dialog) {
- super.onDismiss(dialog);
- if (!requireActivity().isChangingConfigurations()) {
- requireActivity().finish();
- }
- }
-
- private void setSuccessResultWithSelectedRingtone() {
- requireActivity().setResult(Activity.RESULT_OK,
- new Intent().putExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI,
- mRingtonePickerViewModel.getSelectedRingtoneUri()));
- }
-
- /**
- * Inflates the tabbed layout view and adds the required fragments. If there's only one
- * fragment to display, then the tab area is hidden.
- * @param inflater The LayoutInflater that is used to inflate the tabbed view.
- * @return The tabbed view.
- */
- private View buildTabbedView(@NonNull LayoutInflater inflater) {
- View view = inflater.inflate(R.layout.fragment_tabbed_dialog, null, false);
- TabLayout tabLayout = view.requireViewById(R.id.tabLayout);
- ViewPager2 viewPager = view.requireViewById(R.id.masterViewPager);
-
- ViewPagerAdapter adapter = new ViewPagerAdapter(requireActivity());
- addFragments(adapter);
-
- if (adapter.getItemCount() == 1) {
- // Hide the tab area since there's only one fragment to display.
- tabLayout.setVisibility(View.GONE);
- }
-
- viewPager.setAdapter(adapter);
- viewPager.registerOnPageChangeCallback(mOnPageChangeCallback);
- new TabLayoutMediator(tabLayout, viewPager,
- (tab, position) -> tab.setText(adapter.getTitle(position))).attach();
-
- return view;
- }
-
- /**
- * Adds the appropriate fragments to the adapter based on the PickerType.
- *
- * @param adapter The adapter to add the fragments to.
- */
- private void addFragments(ViewPagerAdapter adapter) {
- switch (mRingtonePickerViewModel.getPickerConfig().mPickerType) {
- case RINGTONE_PICKER:
- adapter.addFragment(getString(R.string.sound_page_title),
- new SoundPickerFragment());
- adapter.addFragment(getString(R.string.vibration_page_title),
- new VibrationPickerFragment());
- break;
- case SOUND_PICKER:
- adapter.addFragment(getString(R.string.sound_page_title),
- new SoundPickerFragment());
- break;
- case VIBRATION_PICKER:
- adapter.addFragment(getString(R.string.vibration_page_title),
- new VibrationPickerFragment());
- break;
- default:
- adapter.addFragment(getString(R.string.sound_page_title),
- new SoundPickerFragment());
- break;
- }
- }
-}
diff --git a/packages/SoundPicker2/src/com/android/soundpicker/VibrationPickerFragment.java b/packages/SoundPicker2/src/com/android/soundpicker/VibrationPickerFragment.java
deleted file mode 100644
index 7412c1995b5a..000000000000
--- a/packages/SoundPicker2/src/com/android/soundpicker/VibrationPickerFragment.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2023 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.soundpicker;
-
-import android.os.Bundle;
-import android.view.View;
-
-import androidx.lifecycle.ViewModelProvider;
-
-import org.jetbrains.annotations.NotNull;
-
-/**
- * A fragment that displays a picker used to select vibration or silent (no vibration).
- */
-public class VibrationPickerFragment extends BasePickerFragment {
-
- @Override
- public void onViewCreated(@NotNull View view, Bundle savedInstanceState) {
- mRingtonePickerViewModel = new ViewModelProvider(requireActivity()).get(
- RingtonePickerViewModel.class);
- super.onViewCreated(view, savedInstanceState);
- }
-
- @Override
- protected RingtoneListHandler getRingtoneListHandler() {
- return mRingtonePickerViewModel.getVibrationListHandler();
- }
-
- @Override
- protected void addRingtoneAsync() {
- // no-op
- }
-
- @Override
- protected void addNewRingtoneItem() {
- // no-op
- }
-}
diff --git a/packages/SoundPicker2/src/com/android/soundpicker/ViewPagerAdapter.java b/packages/SoundPicker2/src/com/android/soundpicker/ViewPagerAdapter.java
deleted file mode 100644
index 179068e9f20f..000000000000
--- a/packages/SoundPicker2/src/com/android/soundpicker/ViewPagerAdapter.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2023 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.soundpicker;
-
-import androidx.annotation.NonNull;
-import androidx.fragment.app.Fragment;
-import androidx.fragment.app.FragmentActivity;
-import androidx.viewpager2.adapter.FragmentStateAdapter;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * An adapter used to populate pages inside a ViewPager.
- */
-public class ViewPagerAdapter extends FragmentStateAdapter {
-
- private final List<Fragment> mFragments = new ArrayList<>();
- private final List<String> mTitles = new ArrayList<>();
-
- public ViewPagerAdapter(@NonNull FragmentActivity fragmentActivity) {
- super(fragmentActivity);
- }
-
- /**
- * Adds a fragment and page title to the adapter.
- * @param title the title of the page in the ViewPager.
- * @param fragment the fragment that will be inflated on this page.
- */
- public void addFragment(String title, Fragment fragment) {
- mTitles.add(title);
- mFragments.add(fragment);
- }
-
- /**
- * Returns the title of the requested page.
- * @param position the position of the page in the Viewpager.
- * @return The title of the requested page.
- */
- public String getTitle(int position) {
- return mTitles.get(position);
- }
-
- @NonNull
- @Override
- public Fragment createFragment(int position) {
- return Objects.requireNonNull(mFragments.get(position),
- "Could not find a fragment using position: " + position);
- }
-
- @Override
- public int getItemCount() {
- return mFragments.size();
- }
-}
diff --git a/packages/SoundPicker2/tests/Android.bp b/packages/SoundPicker2/tests/Android.bp
deleted file mode 100644
index d88d442afa17..000000000000
--- a/packages/SoundPicker2/tests/Android.bp
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2023, 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 {
- default_applicable_licenses: ["frameworks_base_license"],
-}
-
-android_test {
- name: "SoundPicker2Tests",
- certificate: "platform",
- libs: [
- "android.test.runner",
- "android.test.base",
- ],
- static_libs: [
- "androidx.test.core",
- "androidx.test.rules",
- "androidx.test.ext.junit",
- "androidx.test.ext.truth",
- "mockito-target-minus-junit4",
- "guava-android-testlib",
- "SoundPicker2Lib",
- ],
- srcs: [
- "src/**/*.java",
- ],
-}
diff --git a/packages/SoundPicker2/tests/AndroidManifest.xml b/packages/SoundPicker2/tests/AndroidManifest.xml
deleted file mode 100644
index 295aeb1faa55..000000000000
--- a/packages/SoundPicker2/tests/AndroidManifest.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.soundpicker.tests">
-
- <application android:debuggable="true">
- <uses-library android:name="android.test.runner" />
- </application>
- <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="com.android.soundpicker.tests"
- android:label="Sound picker tests">
- </instrumentation>
-</manifest>
diff --git a/packages/SoundPicker2/tests/src/com/android/soundpicker/RingtoneListHandlerTest.java b/packages/SoundPicker2/tests/src/com/android/soundpicker/RingtoneListHandlerTest.java
deleted file mode 100644
index 80e71e200a53..000000000000
--- a/packages/SoundPicker2/tests/src/com/android/soundpicker/RingtoneListHandlerTest.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 2023 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.soundpicker;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.when;
-
-import android.database.Cursor;
-import android.media.RingtoneManager;
-import android.net.Uri;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-public class RingtoneListHandlerTest {
-
- private static final Uri DEFAULT_URI = Uri.parse("media://custom/ringtone/default_uri");
- private static final Uri RINGTONE_URI = Uri.parse("media://custom/ringtone/uri");
- private static final int SILENT_RINGTONE_POSITION = 0;
- private static final int DEFAULT_RINGTONE_POSITION = 1;
- private static final int RINGTONE_POSITION = 2;
-
- @Mock
- private RingtoneManager mMockRingtoneManager;
- @Mock
- private Cursor mMockCursor;
-
- private RingtoneListHandler mRingtoneListHandler;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
-
- RingtoneListHandler.Config mRingtoneListConfig = createRingtoneListConfig();
-
- mRingtoneListHandler = new RingtoneListHandler();
-
- // Add silent and default options to the list.
- mRingtoneListHandler.addSilentItem();
- mRingtoneListHandler.addDefaultItem();
-
- mRingtoneListHandler.init(mRingtoneListConfig, mMockRingtoneManager, mMockCursor);
- }
-
- @Test
- public void testGetRingtoneCursor_returnsTheCorrectRingtoneCursor() {
- assertThat(mRingtoneListHandler.getRingtoneCursor()).isEqualTo(mMockCursor);
- }
-
- @Test
- public void testGetRingtoneUri_returnsTheCorrectRingtoneUri() {
- Uri expectedUri = RINGTONE_URI;
- when(mMockRingtoneManager.getRingtoneUri(eq(0))).thenReturn(expectedUri);
-
- // Request 3rd item from list.
- Uri actualUri = mRingtoneListHandler.getRingtoneUri(RINGTONE_POSITION);
- assertThat(actualUri).isEqualTo(expectedUri);
- }
-
- @Test
- public void testGetRingtoneUri_withSelectedItemUnknown_returnsTheCorrectRingtoneUri() {
- Uri uri = mRingtoneListHandler.getRingtoneUri(RingtoneListHandler.ITEM_POSITION_UNKNOWN);
- assertThat(uri).isEqualTo(RingtoneListHandler.SILENT_URI);
- }
-
- @Test
- public void testGetRingtoneUri_withSelectedItemDefaultPosition_returnsTheCorrectRingtoneUri() {
- Uri actualUri = mRingtoneListHandler.getRingtoneUri(DEFAULT_RINGTONE_POSITION);
- assertThat(actualUri).isEqualTo(DEFAULT_URI);
- }
-
- @Test
- public void testGetRingtoneUri_withSelectedItemSilentPosition_returnsTheCorrectRingtoneUri() {
- Uri uri = mRingtoneListHandler.getRingtoneUri(SILENT_RINGTONE_POSITION);
- assertThat(uri).isEqualTo(RingtoneListHandler.SILENT_URI);
- }
-
- @Test
- public void testGetCurrentlySelectedRingtoneUri_returnsTheCorrectRingtoneUri() {
- mRingtoneListHandler.setSelectedItemPosition(RingtoneListHandler.ITEM_POSITION_UNKNOWN);
- Uri actualUri = mRingtoneListHandler.getSelectedRingtoneUri();
- assertThat(actualUri).isEqualTo(RingtoneListHandler.SILENT_URI);
-
- mRingtoneListHandler.setSelectedItemPosition(DEFAULT_RINGTONE_POSITION);
- actualUri = mRingtoneListHandler.getSelectedRingtoneUri();
- assertThat(actualUri).isEqualTo(DEFAULT_URI);
-
- mRingtoneListHandler.setSelectedItemPosition(SILENT_RINGTONE_POSITION);
- actualUri = mRingtoneListHandler.getSelectedRingtoneUri();
- assertThat(actualUri).isEqualTo(RingtoneListHandler.SILENT_URI);
-
- when(mMockRingtoneManager.getRingtoneUri(eq(0))).thenReturn(RINGTONE_URI);
- mRingtoneListHandler.setSelectedItemPosition(RINGTONE_POSITION);
- actualUri = mRingtoneListHandler.getSelectedRingtoneUri();
- assertThat(actualUri).isEqualTo(RINGTONE_URI);
- }
-
- @Test
- public void testGetRingtonePosition_returnsTheCorrectRingtonePosition() {
- when(mMockRingtoneManager.getRingtonePosition(RINGTONE_URI)).thenReturn(0);
-
- int actualPosition = mRingtoneListHandler.getRingtonePosition(RINGTONE_URI);
-
- assertThat(actualPosition).isEqualTo(RINGTONE_POSITION);
-
- }
-
- @Test
- public void testFixedItems_onlyAddsItemsOnceAndInOrder() {
- // Clear fixed items before testing the add methods.
- mRingtoneListHandler.resetFixedItems();
-
- assertThat(mRingtoneListHandler.getSilentItemPosition()).isEqualTo(
- RingtoneListHandler.ITEM_POSITION_UNKNOWN);
- assertThat(mRingtoneListHandler.getDefaultItemPosition()).isEqualTo(
- RingtoneListHandler.ITEM_POSITION_UNKNOWN);
-
- mRingtoneListHandler.addSilentItem();
- mRingtoneListHandler.addDefaultItem();
- mRingtoneListHandler.addSilentItem();
- mRingtoneListHandler.addDefaultItem();
-
- assertThat(mRingtoneListHandler.getSilentItemPosition()).isEqualTo(
- SILENT_RINGTONE_POSITION);
- assertThat(mRingtoneListHandler.getDefaultItemPosition()).isEqualTo(
- DEFAULT_RINGTONE_POSITION);
- }
-
- @Test
- public void testResetFixedItems_resetsSilentAndDefaultItemPositions() {
- assertThat(mRingtoneListHandler.getSilentItemPosition()).isEqualTo(
- SILENT_RINGTONE_POSITION);
- assertThat(mRingtoneListHandler.getDefaultItemPosition()).isEqualTo(
- DEFAULT_RINGTONE_POSITION);
-
- mRingtoneListHandler.resetFixedItems();
-
- assertThat(mRingtoneListHandler.getSilentItemPosition()).isEqualTo(
- RingtoneListHandler.ITEM_POSITION_UNKNOWN);
- assertThat(mRingtoneListHandler.getDefaultItemPosition()).isEqualTo(
- RingtoneListHandler.ITEM_POSITION_UNKNOWN);
- }
-
- private RingtoneListHandler.Config createRingtoneListConfig() {
- return new RingtoneListHandler.Config(/* hasDefaultItem= */ true,
- /* uriForDefaultItem= */ DEFAULT_URI, /* hasSilentItem= */ true,
- /* existingUri= */ DEFAULT_URI);
- }
-}
diff --git a/packages/SoundPicker2/tests/src/com/android/soundpicker/RingtonePickerViewModelTest.java b/packages/SoundPicker2/tests/src/com/android/soundpicker/RingtonePickerViewModelTest.java
deleted file mode 100644
index cde6c76d27ff..000000000000
--- a/packages/SoundPicker2/tests/src/com/android/soundpicker/RingtonePickerViewModelTest.java
+++ /dev/null
@@ -1,534 +0,0 @@
-/*
- * Copyright (C) 2023 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.soundpicker;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertNull;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import android.database.Cursor;
-import android.media.AudioAttributes;
-import android.media.AudioManager;
-import android.media.Ringtone;
-import android.media.RingtoneManager;
-import android.net.Uri;
-import android.provider.Settings;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.ListeningExecutorService;
-import com.google.common.util.concurrent.testing.TestingExecutors;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.io.IOException;
-import java.util.concurrent.ExecutorService;
-
-@RunWith(AndroidJUnit4.class)
-public class RingtonePickerViewModelTest {
-
- private static final Uri DEFAULT_URI = Uri.parse("media://custom/ringtone/default_uri");
- private static final Uri RINGTONE_URI = Uri.parse("media://custom/ringtone/uri");
- private static final int RINGTONE_TYPE_UNKNOWN = -1;
- private static final int DEFAULT_RINGTONE_POSITION = 1;
-
- @Mock
- private RingtoneManagerFactory mMockRingtoneManagerFactory;
- @Mock
- private RingtoneFactory mMockRingtoneFactory;
- @Mock
- private RingtoneManager mMockRingtoneManager;
- @Mock
- private ListeningExecutorServiceFactory mMockListeningExecutorServiceFactory;
- @Mock
- private Cursor mMockCursor;
-
- private RingtoneListHandler mSoundListHandler;
- private RingtoneListHandler mVibrationListHandler;
- private ExecutorService mMainThreadExecutor;
- private ListeningExecutorService mBackgroundThreadExecutor;
- private Ringtone mMockDefaultRingtone;
- private Ringtone mMockRingtone;
- private RingtonePickerViewModel mViewModel;
- private RingtoneListHandler.Config mSoundListConfig;
- private RingtoneListHandler.Config mVibrationListConfig;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
-
- mSoundListHandler = new RingtoneListHandler();
- mVibrationListHandler = new RingtoneListHandler();
- mSoundListConfig = createRingtoneListConfig();
- mVibrationListConfig = createRingtoneListConfig();
- mMockDefaultRingtone = createMockRingtone();
- mMockRingtone = createMockRingtone();
- when(mMockRingtoneManagerFactory.create()).thenReturn(mMockRingtoneManager);
- when(mMockRingtoneFactory.create(DEFAULT_URI,
- AudioAttributes.FLAG_AUDIBILITY_ENFORCED)).thenReturn(mMockDefaultRingtone);
- when(mMockRingtoneManager.getRingtoneUri(anyInt())).thenReturn(RINGTONE_URI);
- when(mMockRingtoneManager.getCursor()).thenReturn(mMockCursor);
- mMainThreadExecutor = TestingExecutors.sameThreadScheduledExecutor();
- mBackgroundThreadExecutor = TestingExecutors.sameThreadScheduledExecutor();
- when(mMockListeningExecutorServiceFactory.createSingleThreadExecutor()).thenReturn(
- mBackgroundThreadExecutor);
-
- mViewModel = new RingtonePickerViewModel(mMockRingtoneManagerFactory, mMockRingtoneFactory,
- mMockListeningExecutorServiceFactory, mSoundListHandler,
- mVibrationListHandler);
-
- // Add silent and default options to the sound list.
- mSoundListHandler.addSilentItem();
- mSoundListHandler.addDefaultItem();
-
- // Add silent and default options to the vibration list.
- mVibrationListHandler.addSilentItem();
- mVibrationListHandler.addDefaultItem();
-
- mSoundListHandler.setSelectedItemPosition(DEFAULT_RINGTONE_POSITION);
- mVibrationListHandler.setSelectedItemPosition(DEFAULT_RINGTONE_POSITION);
- }
-
- @After
- public void teardown() {
- if (mMainThreadExecutor != null && !mMainThreadExecutor.isShutdown()) {
- mMainThreadExecutor.shutdown();
- }
- if (mBackgroundThreadExecutor != null && !mBackgroundThreadExecutor.isShutdown()) {
- mBackgroundThreadExecutor.shutdown();
- }
- }
-
- @Test
- public void testInitRingtoneManager_whenTypeIsUnknown_createManagerButDoNotSetType() {
- mViewModel.init(createPickerConfig(RINGTONE_TYPE_UNKNOWN), mSoundListConfig,
- mVibrationListConfig);
-
- verify(mMockRingtoneManagerFactory).create();
- verify(mMockRingtoneManager, never()).setType(anyInt());
- assertNotNull(mViewModel.getSoundListHandler().getRingtoneListConfig());
- assertNotNull(mViewModel.getVibrationListHandler().getRingtoneListConfig());
- }
-
- @Test
- public void testInitRingtoneManager_whenTypeIsNotUnknown_createManagerAndSetType() {
- mViewModel.init(createPickerConfig(RingtoneManager.TYPE_NOTIFICATION), mSoundListConfig,
- mVibrationListConfig);
-
- verify(mMockRingtoneManagerFactory).create();
- verify(mMockRingtoneManager).setType(RingtoneManager.TYPE_NOTIFICATION);
- assertNotNull(mViewModel.getSoundListHandler().getRingtoneListConfig());
- assertNotNull(mViewModel.getVibrationListHandler().getRingtoneListConfig());
- }
-
- @Test
- public void testInitRingtoneManager_bothListConfigsAreNull_onlyRecreateRingtoneManager() {
- mViewModel.init(
- createPickerConfig(RingtoneManager.TYPE_NOTIFICATION),
- /* soundListConfig= */ null, /* vibrationListConfig= */ null);
-
- verify(mMockRingtoneManagerFactory).create();
- verify(mMockRingtoneManager).setType(RingtoneManager.TYPE_NOTIFICATION);
- assertNull(mViewModel.getSoundListHandler().getRingtoneListConfig());
- assertNull(mViewModel.getVibrationListHandler().getRingtoneListConfig());
- }
-
- @Test
- public void testReinitialize_bothListConfigsInitialized_recreateManagerAndReinitHandlers() {
- mViewModel.init(createPickerConfig(RingtoneManager.TYPE_NOTIFICATION), mSoundListConfig,
- mVibrationListConfig);
- mViewModel.reinit();
-
- verify(mMockRingtoneManagerFactory, times(2)).create();
- verify(mMockRingtoneManager, times(2)).setType(RingtoneManager.TYPE_NOTIFICATION);
- assertNotNull(mViewModel.getSoundListHandler().getRingtoneListConfig());
- assertNotNull(mViewModel.getVibrationListHandler().getRingtoneListConfig());
- }
-
- @Test
- public void testReinitialize_bothListConfigsAlreadyNull_onlyRecreateRingtoneManager() {
- mViewModel.init(
- createPickerConfig(RingtoneManager.TYPE_NOTIFICATION),
- /* soundListConfig= */ null, /* vibrationListConfig= */ null);
- mViewModel.reinit();
-
- verify(mMockRingtoneManagerFactory, times(2)).create();
- verify(mMockRingtoneManager, times(2)).setType(RingtoneManager.TYPE_NOTIFICATION);
- assertNull(mViewModel.getSoundListHandler().getRingtoneListConfig());
- assertNull(mViewModel.getVibrationListHandler().getRingtoneListConfig());
- }
-
- @Test
- public void testGetStreamType_returnsTheCorrectStreamType() {
- when(mMockRingtoneManager.inferStreamType()).thenReturn(AudioManager.STREAM_ALARM);
- mViewModel.init(createPickerConfig(RingtoneManager.TYPE_RINGTONE), mSoundListConfig,
- mVibrationListConfig);
- assertEquals(mViewModel.getRingtoneStreamType(), AudioManager.STREAM_ALARM);
- }
-
- @Test
- public void testOnPause_withChangingConfigurationTrue_doNotStopPlayingRingtone() {
- mViewModel.init(createPickerConfig(RingtoneManager.TYPE_RINGTONE), mSoundListConfig,
- mVibrationListConfig);
- mViewModel.playRingtone();
- verifyRingtonePlayCalledAndMockPlayingState(mMockDefaultRingtone);
- mViewModel.onPause(/* isChangingConfigurations= */ true);
- verify(mMockDefaultRingtone, never()).stop();
- }
-
- @Test
- public void testOnPause_withChangingConfigurationFalse_stopPlayingRingtone() {
- mViewModel.init(createPickerConfig(RingtoneManager.TYPE_RINGTONE), mSoundListConfig,
- mVibrationListConfig);
- mViewModel.playRingtone();
- verifyRingtonePlayCalledAndMockPlayingState(mMockDefaultRingtone);
- mViewModel.onPause(/* isChangingConfigurations= */ false);
- verify(mMockDefaultRingtone).stop();
- }
-
- @Test
- public void testOnViewModelRecreated_previousRingtoneCanStillBeStopped() {
- mViewModel.init(createPickerConfig(RingtoneManager.TYPE_RINGTONE), mSoundListConfig,
- mVibrationListConfig);
- Ringtone mockRingtone1 = createMockRingtone();
- Ringtone mockRingtone2 = createMockRingtone();
-
- when(mMockRingtoneFactory.create(any(), anyInt())).thenReturn(mockRingtone1, mockRingtone2);
- mViewModel.playRingtone();
- verifyRingtonePlayCalledAndMockPlayingState(mockRingtone1);
- // Fake a scenario where the activity is destroyed and recreated due to a config change.
- // This will result in a new view model getting created.
- mViewModel.onStop(/* isChangingConfigurations= */ true);
- verify(mockRingtone1, never()).stop();
- mViewModel = new RingtonePickerViewModel(mMockRingtoneManagerFactory, mMockRingtoneFactory,
- mMockListeningExecutorServiceFactory, mSoundListHandler,
- mVibrationListHandler);
- mViewModel.init(createPickerConfig(RingtoneManager.TYPE_RINGTONE), mSoundListConfig,
- mVibrationListConfig);
- mViewModel.playRingtone();
- verifyRingtonePlayCalledAndMockPlayingState(mockRingtone2);
- verify(mockRingtone1).stop();
- verify(mockRingtone2, never()).stop();
- }
-
- @Test
- public void testOnStop_withChangingConfigurationTrueAndDefaultRingtonePlaying_saveRingtone() {
- mViewModel.init(createPickerConfig(RingtoneManager.TYPE_RINGTONE), mSoundListConfig,
- mVibrationListConfig);
- mViewModel.playRingtone();
- verifyRingtonePlayCalledAndMockPlayingState(mMockDefaultRingtone);
- mViewModel.onStop(/* isChangingConfigurations= */ true);
- assertEquals(RingtonePickerViewModel.sPlayingRingtone, mMockDefaultRingtone);
- }
-
- @Test
- public void testOnStop_withChangingConfigurationTrueAndCurrentRingtonePlaying_saveRingtone() {
- mViewModel.init(createPickerConfig(RingtoneManager.TYPE_RINGTONE), mSoundListConfig,
- mVibrationListConfig);
- mViewModel.playRingtone();
- verifyRingtonePlayCalledAndMockPlayingState(mMockDefaultRingtone);
- mViewModel.onStop(/* isChangingConfigurations= */ true);
- assertEquals(RingtonePickerViewModel.sPlayingRingtone, mMockDefaultRingtone);
- }
-
- @Test
- public void testOnStop_withChangingConfigurationTrueAndNoPlayingRingtone_saveNothing() {
- mViewModel.onStop(/* isChangingConfigurations= */ true);
- assertNull(RingtonePickerViewModel.sPlayingRingtone);
- }
-
- @Test
- public void testOnStop_withChangingConfigurationFalse_stopPlayingRingtone() {
- mViewModel.init(createPickerConfig(RingtoneManager.TYPE_RINGTONE), mSoundListConfig,
- mVibrationListConfig);
-
- mViewModel.playRingtone();
- verifyRingtonePlayCalledAndMockPlayingState(mMockDefaultRingtone);
- mViewModel.onStop(/* isChangingConfigurations= */ false);
- verify(mMockDefaultRingtone).stop();
- }
-
- @Test
- public void testGetCurrentlySelectedRingtoneUri_returnsTheCorrectRingtoneUri() {
- mViewModel.init(createPickerConfig(RingtoneManager.TYPE_RINGTONE), mSoundListConfig,
- mVibrationListConfig);
-
- assertEquals(DEFAULT_URI, mViewModel.getSelectedRingtoneUri());
- }
-
- @Test
- public void testPlayRingtone_playTheCorrectRingtone() {
- mSoundListHandler.setSelectedItemPosition(DEFAULT_RINGTONE_POSITION);
- mViewModel.init(createPickerConfig(RingtoneManager.TYPE_RINGTONE), mSoundListConfig,
- mVibrationListConfig);
-
- mViewModel.playRingtone();
- verifyRingtonePlayCalledAndMockPlayingState(mMockDefaultRingtone);
- }
-
- @Test
- public void testPlayRingtone_stopsPreviouslyRunningRingtone() {
- // Start playing the first ringtone
- mViewModel.init(createPickerConfig(RingtoneManager.TYPE_RINGTONE), mSoundListConfig,
- mVibrationListConfig);
- mViewModel.playRingtone();
- verifyRingtonePlayCalledAndMockPlayingState(mMockDefaultRingtone);
- // Start playing the second ringtone
- when(mMockRingtoneFactory.create(DEFAULT_URI,
- AudioAttributes.FLAG_AUDIBILITY_ENFORCED)).thenReturn(mMockRingtone);
- mViewModel.playRingtone();
- verifyRingtonePlayCalledAndMockPlayingState(mMockRingtone);
-
- verify(mMockDefaultRingtone).stop();
- }
-
- @Test
- public void testDefaultItemUri_withNotificationIntent_returnDefaultNotificationUri() {
- Uri uri = RingtonePickerViewModel.getDefaultItemUriByType(
- RingtoneManager.TYPE_NOTIFICATION);
- assertEquals(Settings.System.DEFAULT_NOTIFICATION_URI, uri);
- }
-
- @Test
- public void testDefaultItemUri_withAlarmIntent_returnDefaultAlarmUri() {
- Uri uri = RingtonePickerViewModel.getDefaultItemUriByType(RingtoneManager.TYPE_ALARM);
- assertEquals(Settings.System.DEFAULT_ALARM_ALERT_URI, uri);
- }
-
- @Test
- public void testDefaultItemUri_withRingtoneIntent_returnDefaultRingtoneUri() {
- Uri uri = RingtonePickerViewModel.getDefaultItemUriByType(RingtoneManager.TYPE_RINGTONE);
- assertEquals(Settings.System.DEFAULT_RINGTONE_URI, uri);
- }
-
- @Test
- public void testDefaultItemUri_withInvalidRingtoneType_returnDefaultRingtoneUri() {
- Uri uri = RingtonePickerViewModel.getDefaultItemUriByType(-1);
- assertEquals(Settings.System.DEFAULT_RINGTONE_URI, uri);
- }
-
- @Test
- public void testTitle_withNotificationRingtoneType_returnRingtoneNotificationTitle() {
- int title = RingtonePickerViewModel.getTitleByType(RingtoneManager.TYPE_NOTIFICATION);
- assertEquals(com.android.internal.R.string.ringtone_picker_title_notification, title);
- }
-
- @Test
- public void testTitle_withAlarmRingtoneType_returnRingtoneAlarmTitle() {
- int title = RingtonePickerViewModel.getTitleByType(RingtoneManager.TYPE_ALARM);
- assertEquals(com.android.internal.R.string.ringtone_picker_title_alarm, title);
- }
-
- @Test
- public void testTitle_withInvalidRingtoneType_returnDefaultRingtoneTitle() {
- int title = RingtonePickerViewModel.getTitleByType(/*ringtoneType= */ -1);
- assertEquals(com.android.internal.R.string.ringtone_picker_title, title);
- }
-
- @Test
- public void testAddNewItemText_withAlarmType_returnAlarmAddItemText() {
- int addNewItemTextResId = RingtonePickerViewModel.getAddNewItemTextByType(
- RingtoneManager.TYPE_ALARM);
- assertEquals(R.string.add_alarm_text, addNewItemTextResId);
- }
-
- @Test
- public void testAddNewItemText_withNotificationType_returnNotificationAddItemText() {
- int addNewItemTextResId = RingtonePickerViewModel.getAddNewItemTextByType(
- RingtoneManager.TYPE_NOTIFICATION);
- assertEquals(R.string.add_notification_text, addNewItemTextResId);
- }
-
- @Test
- public void testAddNewItemText_withRingtoneType_returnRingtoneAddItemText() {
- int addNewItemTextResId = RingtonePickerViewModel.getAddNewItemTextByType(
- RingtoneManager.TYPE_RINGTONE);
- assertEquals(R.string.add_ringtone_text, addNewItemTextResId);
- }
-
- @Test
- public void testAddNewItemText_withInvalidType_returnRingtoneAddItemText() {
- int addNewItemTextResId = RingtonePickerViewModel.getAddNewItemTextByType(-1);
- assertEquals(R.string.add_ringtone_text, addNewItemTextResId);
- }
-
- @Test
- public void testDefaultItemText_withNotificationType_returnNotificationDefaultItemText() {
- int defaultRingtoneItemText = RingtonePickerViewModel.getDefaultRingtoneItemTextByType(
- RingtoneManager.TYPE_NOTIFICATION);
- assertEquals(R.string.notification_sound_default, defaultRingtoneItemText);
- }
-
- @Test
- public void testDefaultItemText_withAlarmType_returnAlarmDefaultItemText() {
- int defaultRingtoneItemText = RingtonePickerViewModel.getDefaultRingtoneItemTextByType(
- RingtoneManager.TYPE_NOTIFICATION);
- assertEquals(R.string.notification_sound_default, defaultRingtoneItemText);
- }
-
- @Test
- public void testDefaultItemText_withRingtoneType_returnRingtoneDefaultItemText() {
- int defaultRingtoneItemText = RingtonePickerViewModel.getDefaultRingtoneItemTextByType(
- RingtoneManager.TYPE_RINGTONE);
- assertEquals(R.string.ringtone_default, defaultRingtoneItemText);
- }
-
- @Test
- public void testDefaultItemText_withInvalidType_returnRingtoneDefaultItemText() {
- int defaultRingtoneItemText = RingtonePickerViewModel.getDefaultRingtoneItemTextByType(-1);
- assertEquals(R.string.ringtone_default, defaultRingtoneItemText);
- }
-
- @Test
- public void testCancelPendingAsyncTasks_correctlyCancelsPendingTasks()
- throws IOException {
- FutureCallback<Uri> mockCallback = mock(FutureCallback.class);
-
- when(mMockListeningExecutorServiceFactory.createSingleThreadExecutor()).thenReturn(
- TestingExecutors.noOpScheduledExecutor());
-
- mViewModel = new RingtonePickerViewModel(mMockRingtoneManagerFactory, mMockRingtoneFactory,
- mMockListeningExecutorServiceFactory, mSoundListHandler,
- mVibrationListHandler);
- mViewModel.addSoundRingtoneAsync(DEFAULT_URI, RingtoneManager.TYPE_NOTIFICATION,
- mockCallback, mMainThreadExecutor);
- verify(mockCallback, never()).onFailure(any());
- // Calling cancelPendingAsyncTasks should cancel the pending task. Cancelling an async
- // task invokes the onFailure method in the callable.
- mViewModel.cancelPendingAsyncTasks();
- verify(mockCallback).onFailure(any());
- verify(mockCallback, never()).onSuccess(any());
-
- }
-
- @Test
- public void testAddRingtoneAsync_cancelPreviousTaskBeforeStartingNewOne()
- throws IOException {
- FutureCallback<Uri> mockCallback1 = mock(FutureCallback.class);
- FutureCallback<Uri> mockCallback2 = mock(FutureCallback.class);
-
- when(mMockListeningExecutorServiceFactory.createSingleThreadExecutor()).thenReturn(
- TestingExecutors.noOpScheduledExecutor());
-
- mViewModel = new RingtonePickerViewModel(mMockRingtoneManagerFactory, mMockRingtoneFactory,
- mMockListeningExecutorServiceFactory, mSoundListHandler,
- mVibrationListHandler);
- mViewModel.addSoundRingtoneAsync(DEFAULT_URI, RingtoneManager.TYPE_NOTIFICATION,
- mockCallback1, mMainThreadExecutor);
- verify(mockCallback1, never()).onFailure(any());
- // We call addRingtoneAsync again to cancel the previous task and start a new one.
- // Cancelling an async task invokes the onFailure method in the callable.
- mViewModel.addSoundRingtoneAsync(DEFAULT_URI, RingtoneManager.TYPE_NOTIFICATION,
- mockCallback2, mMainThreadExecutor);
- verify(mockCallback1).onFailure(any());
- verify(mockCallback1, never()).onSuccess(any());
- verifyNoMoreInteractions(mockCallback2);
- }
-
- @Test
- public void testAddRingtoneAsync_whenAddRingtoneIsSuccessful_successCallbackIsInvoked()
- throws IOException {
- Uri expectedUri = DEFAULT_URI;
- FutureCallback<Uri> mockCallback = mock(FutureCallback.class);
-
- when(mMockRingtoneManager.addCustomExternalRingtone(DEFAULT_URI,
- RingtoneManager.TYPE_NOTIFICATION)).thenReturn(expectedUri);
-
- mViewModel.init(createPickerConfig(RingtoneManager.TYPE_RINGTONE), mSoundListConfig,
- mVibrationListConfig);
-
- mViewModel.addSoundRingtoneAsync(DEFAULT_URI, RingtoneManager.TYPE_NOTIFICATION,
- mockCallback, mMainThreadExecutor);
-
- verify(mockCallback).onSuccess(expectedUri);
- verify(mockCallback, never()).onFailure(any());
- }
-
- @Test
- public void testAddRingtoneAsync_whenAddRingtoneFailed_failureCallbackIsInvoked()
- throws IOException {
- FutureCallback<Uri> mockCallback = mock(FutureCallback.class);
-
- when(mMockRingtoneManager.addCustomExternalRingtone(any(), anyInt())).thenThrow(
- IOException.class);
-
- mViewModel.init(createPickerConfig(RingtoneManager.TYPE_RINGTONE), mSoundListConfig,
- mVibrationListConfig);
-
- mViewModel.addSoundRingtoneAsync(DEFAULT_URI, RingtoneManager.TYPE_NOTIFICATION,
- mockCallback, mMainThreadExecutor);
-
- verify(mockCallback).onFailure(any(IOException.class));
- verify(mockCallback, never()).onSuccess(any());
- }
-
- private Ringtone createMockRingtone() {
- Ringtone mockRingtone = mock(Ringtone.class);
- when(mockRingtone.getAudioAttributes()).thenReturn(
- audioAttributes(AudioAttributes.USAGE_NOTIFICATION_RINGTONE, 0));
-
- return mockRingtone;
- }
-
- private void verifyRingtonePlayCalledAndMockPlayingState(Ringtone ringtone) {
- verify(ringtone).play();
- when(ringtone.isPlaying()).thenReturn(true);
- }
-
- private static AudioAttributes audioAttributes(int audioUsage, int flags) {
- return new AudioAttributes.Builder()
- .setUsage(audioUsage)
- .setFlags(flags)
- .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
- .build();
- }
-
- private RingtonePickerViewModel.Config createPickerConfig(int ringtoneType,
- int audioAttributes) {
- return new RingtonePickerViewModel.Config("Phone ringtone", /* userId= */ 1,
- ringtoneType, /* showOkCancelButtons= */ true,
- audioAttributes, RingtonePickerViewModel.PickerType.RINGTONE_PICKER);
- }
-
- private RingtonePickerViewModel.Config createPickerConfig(int ringtoneType) {
- return new RingtonePickerViewModel.Config("Phone ringtone", /* userId= */ 1,
- ringtoneType, /* showOkCancelButtons= */ true,
- AudioAttributes.FLAG_AUDIBILITY_ENFORCED,
- RingtonePickerViewModel.PickerType.RINGTONE_PICKER);
- }
-
- private RingtoneListHandler.Config createRingtoneListConfig() {
- return new RingtoneListHandler.Config(/* hasDefaultItem= */ true,
- /* uriForDefaultItem= */ DEFAULT_URI, /* hasSilentItem= */ true,
- /* existingUri= */ Uri.parse(""));
- }
-}