133781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux/*
233781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux * Copyright (C) 2016 The Android Open Source Project
333781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux *
433781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux * Licensed under the Apache License, Version 2.0 (the "License");
533781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux * you may not use this file except in compliance with the License.
633781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux * You may obtain a copy of the License at
733781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux *
833781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux *      http://www.apache.org/licenses/LICENSE-2.0
933781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux *
1033781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux * Unless required by applicable law or agreed to in writing, software
1133781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux * distributed under the License is distributed on an "AS IS" BASIS,
1233781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1333781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux * See the License for the specific language governing permissions and
1433781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux * limitations under the License.
1533781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux */
1633781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux
1733781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieuxpackage com.android.deskclock.ringtone;
1833781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux
1933781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieuximport android.content.AsyncTaskLoader;
2033781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieuximport android.content.Context;
2133781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieuximport android.database.Cursor;
2233781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieuximport android.database.MatrixCursor;
2333781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieuximport android.media.RingtoneManager;
2433781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieuximport android.net.Uri;
2533781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux
2633781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieuximport com.android.deskclock.ItemAdapter;
2733781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieuximport com.android.deskclock.LogUtils;
2833781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieuximport com.android.deskclock.R;
2933781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieuximport com.android.deskclock.data.CustomRingtone;
3033781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieuximport com.android.deskclock.data.DataModel;
3133781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux
3233781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieuximport java.util.ArrayList;
3333781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieuximport java.util.List;
3433781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux
3533781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieuximport static android.media.AudioManager.STREAM_ALARM;
3633781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieuximport static com.android.deskclock.Utils.RINGTONE_SILENT;
3733781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux
3833781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux/**
3933781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux * Assembles the list of ItemHolders that back the RecyclerView used to choose a ringtone.
4033781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux */
4133781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieuxclass RingtoneLoader extends AsyncTaskLoader<List<ItemAdapter.ItemHolder<Uri>>> {
4233781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux
4333781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux    private final Uri mDefaultRingtoneUri;
4433781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux    private final String mDefaultRingtoneTitle;
4533781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux    private List<CustomRingtone> mCustomRingtones;
4633781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux
4733781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux    RingtoneLoader(Context context, Uri defaultRingtoneUri, String defaultRingtoneTitle) {
4833781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux        super(context);
4933781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux        mDefaultRingtoneUri = defaultRingtoneUri;
5033781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux        mDefaultRingtoneTitle = defaultRingtoneTitle;
5133781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux    }
5233781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux
5333781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux    @Override
5433781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux    protected void onStartLoading() {
5533781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux        super.onStartLoading();
5633781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux
5733781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux        mCustomRingtones = DataModel.getDataModel().getCustomRingtones();
5833781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux        forceLoad();
5933781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux    }
6033781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux
6133781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux    @Override
6233781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux    public List<ItemAdapter.ItemHolder<Uri>> loadInBackground() {
63c9446b52d9391e859e65d11e5342d84cfe3e781cJames Lemieux        // Prime the ringtone title cache for later access.
64c9446b52d9391e859e65d11e5342d84cfe3e781cJames Lemieux        DataModel.getDataModel().loadRingtoneTitles();
6595eed3212011413e1cb717c281e2157859a5adf4Sean Stout        DataModel.getDataModel().loadRingtonePermissions();
66c9446b52d9391e859e65d11e5342d84cfe3e781cJames Lemieux
6733781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux        // Fetch the standard system ringtones.
6833781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux        final RingtoneManager ringtoneManager = new RingtoneManager(getContext());
6933781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux        ringtoneManager.setType(STREAM_ALARM);
7033781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux
7133781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux        Cursor systemRingtoneCursor;
7233781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux        try {
7333781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux            systemRingtoneCursor = ringtoneManager.getCursor();
7433781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux        } catch (Exception e) {
7533781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux            LogUtils.e("Could not get system ringtone cursor");
7633781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux            systemRingtoneCursor = new MatrixCursor(new String[] {});
7733781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux        }
7833781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux        final int systemRingtoneCount = systemRingtoneCursor.getCount();
7933781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux        // item count = # system ringtones + # custom ringtones + 2 headers + Add new music item
8033781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux        final int itemCount = systemRingtoneCount + mCustomRingtones.size() + 3;
8133781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux
8233781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux        final List<ItemAdapter.ItemHolder<Uri>> itemHolders = new ArrayList<>(itemCount);
8333781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux
8433781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux        // Add the item holder for the Music heading.
852f03dfbbb41a66aefd38d0fbe80cb42afad1f748Sean Stout        itemHolders.add(new HeaderHolder(R.string.your_sounds));
8633781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux
8733781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux        // Add an item holder for each custom ringtone and also cache a pretty name.
8833781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux        for (CustomRingtone ringtone : mCustomRingtones) {
8933781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux            itemHolders.add(new CustomRingtoneHolder(ringtone));
9033781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux        }
9133781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux
9233781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux        // Add an item holder for the "Add new" music ringtone.
9333781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux        itemHolders.add(new AddCustomRingtoneHolder());
9433781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux
9533781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux        // Add an item holder for the Ringtones heading.
962f03dfbbb41a66aefd38d0fbe80cb42afad1f748Sean Stout        itemHolders.add(new HeaderHolder(R.string.device_sounds));
9733781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux
9833781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux        // Add an item holder for the silent ringtone.
9933781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux        itemHolders.add(new SystemRingtoneHolder(RINGTONE_SILENT, null));
10033781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux
10133781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux        // Add an item holder for the system default alarm sound.
10233781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux        itemHolders.add(new SystemRingtoneHolder(mDefaultRingtoneUri, mDefaultRingtoneTitle));
10333781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux
10433781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux        // Add an item holder for each system ringtone.
10533781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux        for (int i = 0; i < systemRingtoneCount; i++) {
10633781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux            final Uri ringtoneUri = ringtoneManager.getRingtoneUri(i);
10733781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux            itemHolders.add(new SystemRingtoneHolder(ringtoneUri, null));
10833781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux        }
10933781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux
11033781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux        return itemHolders;
11133781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux    }
11233781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux
11333781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux    @Override
11433781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux    protected void onReset() {
11533781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux        super.onReset();
11633781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux        mCustomRingtones = null;
11733781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux    }
11833781c882e4229f4ec1a8fafbabb9d4b8b8e2932James Lemieux}