1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.car.settings.sound;
18 
19 import android.annotation.WorkerThread;
20 import android.car.drivingstate.CarUxRestrictions;
21 import android.content.Context;
22 import android.media.AudioAttributes;
23 import android.media.Ringtone;
24 import android.media.RingtoneManager;
25 import android.net.Uri;
26 import android.os.Bundle;
27 
28 import androidx.fragment.app.Fragment;
29 
30 import com.android.car.settings.common.FragmentController;
31 import com.android.car.settings.common.PreferenceController;
32 import com.android.settingslib.utils.ThreadUtils;
33 
34 /** Business logic for changing the default ringtone. */
35 public class RingtonePreferenceController extends PreferenceController<RingtonePreference> {
36 
37     private RingtoneManager mRingtoneManager;
38 
RingtonePreferenceController(Context context, String preferenceKey, FragmentController fragmentController, CarUxRestrictions uxRestrictions)39     public RingtonePreferenceController(Context context, String preferenceKey,
40             FragmentController fragmentController,
41             CarUxRestrictions uxRestrictions) {
42         super(context, preferenceKey, fragmentController, uxRestrictions);
43         mRingtoneManager = new RingtoneManager(context);
44     }
45 
46     @Override
onCreateInternal()47     protected void onCreateInternal() {
48         mRingtoneManager.setType(getPreference().getRingtoneType());
49     }
50 
51     @Override
getPreferenceType()52     protected Class<RingtonePreference> getPreferenceType() {
53         return RingtonePreference.class;
54     }
55 
56     @Override
onStartInternal()57     public void onStartInternal() {
58         super.onStartInternal();
59         ThreadUtils.postOnBackgroundThread(() -> updateSummary(getPreference()));
60     }
61 
62     @Override
handlePreferenceClicked(RingtonePreference preference)63     protected boolean handlePreferenceClicked(RingtonePreference preference) {
64         getFragmentController().launchFragment(createRingtonePickerFragment(preference));
65         return true;
66     }
67 
68     @WorkerThread
updateSummary(RingtonePreference preference)69     private void updateSummary(RingtonePreference preference) {
70         Uri ringtoneUri = RingtoneManager.getActualDefaultRingtoneUri(getContext(),
71                 preference.getRingtoneType());
72         String summary = Ringtone.getTitle(getContext(), ringtoneUri,
73                 /* followSettingsUri= */ false, /* allowRemote= */ true);
74         ThreadUtils.postOnMainThread(() -> preference.setSummary(summary));
75     }
76 
77     /**
78      * Prepares the fragment to launch the ringtone picker. This can be modified
79      * to adjust the parameters of the ringtone picker.
80      */
createRingtonePickerFragment(RingtonePreference ringtonePreference)81     private Fragment createRingtonePickerFragment(RingtonePreference ringtonePreference) {
82         Fragment fragment = new RingtonePickerFragment();
83         Bundle args = fragment.getArguments();
84         if (args == null) {
85             args = new Bundle();
86             fragment.setArguments(args);
87         }
88         args.putCharSequence(RingtoneManager.EXTRA_RINGTONE_TITLE, ringtonePreference.getTitle());
89         args.putInt(RingtoneManager.EXTRA_RINGTONE_TYPE, ringtonePreference.getRingtoneType());
90         args.putBoolean(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT,
91                 ringtonePreference.getShowSilent());
92 
93         // Allow playback in external activity.
94         args.putInt(RingtoneManager.EXTRA_RINGTONE_AUDIO_ATTRIBUTES_FLAGS,
95                 AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY);
96 
97         return fragment;
98     }
99 }
100