/*
 * 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.providers.media;

import android.content.ContentProvider;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
import android.database.Cursor;
import android.database.CursorWrapper;
import android.media.AudioAttributes;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.MediaStore;
import android.provider.Settings;
import android.util.Log;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.CursorAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.android.internal.app.AlertActivity;
import com.android.internal.app.AlertController;

import java.io.IOException;
import java.util.Objects;
import java.util.regex.Pattern;

/**
 * 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
 */
public final class RingtonePickerActivity extends AlertActivity implements
        AdapterView.OnItemSelectedListener, Runnable, DialogInterface.OnClickListener,
        AlertController.AlertParams.OnPrepareListViewListener {

    private static final int POS_UNKNOWN = -1;

    private static final String TAG = "RingtonePickerActivity";

    private static final int DELAY_MS_SELECTION_PLAYED = 300;

    private static final String COLUMN_LABEL = MediaStore.Audio.Media.TITLE;

    private static final String SAVE_CLICKED_POS = "clicked_pos";

    private static final String SOUND_NAME_RES_PREFIX = "sound_name_";

    private static final int ADD_FILE_REQUEST_CODE = 300;

    private RingtoneManager mRingtoneManager;
    private int mType;

    private Cursor mCursor;
    private Handler mHandler;
    private BadgedRingtoneAdapter mAdapter;

    /** The position in the list of the 'Silent' item. */
    private int mSilentPos = POS_UNKNOWN;

    /** The position in the list of the 'Default' item. */
    private int mDefaultRingtonePos = POS_UNKNOWN;

    /** The position in the list of the ringtone to sample. */
    private int mSampleRingtonePos = POS_UNKNOWN;

    /** Whether this list has the 'Silent' item. */
    private boolean mHasSilentItem;

    /** The Uri to place a checkmark next to. */
    private Uri mExistingUri;

    /** The number of static items in the list. */
    private int mStaticItemCount;

    /** Whether this list has the 'Default' item. */
    private boolean mHasDefaultItem;

    /** The Uri to play when the 'Default' item is clicked. */
    private Uri mUriForDefaultItem;

    /** Id of the user to which the ringtone picker should list the ringtones */
    private int mPickerUserId;

    /** Context of the user specified by mPickerUserId */
    private Context mTargetContext;

    /**
     * A Ringtone for the default ringtone. In most cases, the RingtoneManager
     * will stop the previous ringtone. However, the RingtoneManager doesn't
     * manage the default ringtone for us, so we should stop this one manually.
     */
    private Ringtone mDefaultRingtone;

    /**
     * The ringtone that's currently playing, unless the currently playing one is the default
     * ringtone.
     */
    private Ringtone mCurrentRingtone;

    /**
     * Stable ID for the ringtone that is currently checked (may be -1 if no ringtone is checked).
     */
    private long mCheckedItemId = -1;

    private int mAttributesFlags;

    private boolean mShowOkCancelButtons;

    /**
     * Keep the currently playing ringtone around when changing orientation, so that it
     * can be stopped later, after the activity is recreated.
     */
    private static Ringtone sPlayingRingtone;

    private DialogInterface.OnClickListener mRingtoneClickListener =
            new DialogInterface.OnClickListener() {

        /*
         * On item clicked
         */
        public void onClick(DialogInterface dialog, int which) {
            if (which == mCursor.getCount() + mStaticItemCount) {
                // The "Add new ringtone" item was clicked. Start a file picker intent to select
                // only audio files (MIME type "audio/*")
                final Intent chooseFile = new Intent(Intent.ACTION_GET_CONTENT);
                chooseFile.setType("audio/*");
                chooseFile.putExtra(Intent.EXTRA_MIME_TYPES,
                        new String[] { "audio/*", "application/ogg" });
                startActivityForResult(chooseFile, ADD_FILE_REQUEST_CODE);
                return;
            }

            // Save the position of most recently clicked item
            setCheckedItem(which);

            // 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 (!mShowOkCancelButtons) {
                setSuccessResultWithRingtone(getCurrentlySelectedRingtoneUri());
            }

            // Play clip
            playRingtone(which, 0);
        }

    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mHandler = new Handler();

        Intent intent = getIntent();
        mPickerUserId = UserHandle.myUserId();
        mTargetContext = this;

        // Get the types of ringtones to show
        mType = intent.getIntExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, -1);
        initRingtoneManager();

        /*
         * Get whether to show the 'Default' item, and the URI to play when the
         * default is clicked
         */
        mHasDefaultItem = intent.getBooleanExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, true);
        mUriForDefaultItem = intent.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_DEFAULT_URI);
        if (mUriForDefaultItem == null) {
            if (mType == RingtoneManager.TYPE_NOTIFICATION) {
                mUriForDefaultItem = Settings.System.DEFAULT_NOTIFICATION_URI;
            } else if (mType == RingtoneManager.TYPE_ALARM) {
                mUriForDefaultItem = Settings.System.DEFAULT_ALARM_ALERT_URI;
            } else if (mType == RingtoneManager.TYPE_RINGTONE) {
                mUriForDefaultItem = Settings.System.DEFAULT_RINGTONE_URI;
            } else {
                // or leave it null for silence.
                mUriForDefaultItem = Settings.System.DEFAULT_RINGTONE_URI;
            }
        }

        // Get whether to show the 'Silent' item
        mHasSilentItem = intent.getBooleanExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, true);
        // AudioAttributes flags
        mAttributesFlags |= intent.getIntExtra(
                RingtoneManager.EXTRA_RINGTONE_AUDIO_ATTRIBUTES_FLAGS,
                0 /*defaultValue == no flags*/);

        mShowOkCancelButtons = getResources().getBoolean(R.bool.config_showOkCancelButtons);

        // The volume keys will control the stream that we are choosing a ringtone for
        setVolumeControlStream(mRingtoneManager.inferStreamType());

        // Get the URI whose list item should have a checkmark
        mExistingUri = intent
                .getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI);

        // Create the list of ringtones and hold on to it so we can update later.
        mAdapter = new BadgedRingtoneAdapter(this, mCursor,
                /* isManagedProfile = */ UserManager.get(this).isManagedProfile(mPickerUserId));
        if (savedInstanceState != null) {
            setCheckedItem(savedInstanceState.getInt(SAVE_CLICKED_POS, POS_UNKNOWN));
        }

        final AlertController.AlertParams p = mAlertParams;
        p.mAdapter = mAdapter;
        p.mOnClickListener = mRingtoneClickListener;
        p.mLabelColumn = COLUMN_LABEL;
        p.mIsSingleChoice = true;
        p.mOnItemSelectedListener = this;
        if (mShowOkCancelButtons) {
            p.mPositiveButtonText = getString(com.android.internal.R.string.ok);
            p.mPositiveButtonListener = this;
            p.mNegativeButtonText = getString(com.android.internal.R.string.cancel);
            p.mPositiveButtonListener = this;
        }
        p.mOnPrepareListViewListener = this;

        p.mTitle = intent.getCharSequenceExtra(RingtoneManager.EXTRA_RINGTONE_TITLE);
        if (p.mTitle == null) {
          if (mType == RingtoneManager.TYPE_ALARM) {
              p.mTitle = getString(com.android.internal.R.string.ringtone_picker_title_alarm);
          } else if (mType == RingtoneManager.TYPE_NOTIFICATION) {
              p.mTitle =
                  getString(com.android.internal.R.string.ringtone_picker_title_notification);
          } else {
              p.mTitle = getString(com.android.internal.R.string.ringtone_picker_title);
          }
        }

        setupAlert();
    }
    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt(SAVE_CLICKED_POS, getCheckedItem());
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == ADD_FILE_REQUEST_CODE && resultCode == RESULT_OK) {
            // Add the custom ringtone in a separate thread
            final AsyncTask<Uri, Void, Uri> installTask = new AsyncTask<Uri, Void, Uri>() {
                @Override
                protected Uri doInBackground(Uri... params) {
                    try {
                        return mRingtoneManager.addCustomExternalRingtone(params[0], mType);
                    } catch (IOException | IllegalArgumentException e) {
                        Log.e(TAG, "Unable to add new ringtone", e);
                    }
                    return null;
                }

                @Override
                protected void onPostExecute(Uri ringtoneUri) {
                    if (ringtoneUri != null) {
                        requeryForAdapter();
                    } else {
                        // Ringtone was not added, display error Toast
                        Toast.makeText(RingtonePickerActivity.this, R.string.unable_to_add_ringtone,
                                Toast.LENGTH_SHORT).show();
                    }
                }
            };
            installTask.execute(data.getData());
        }
    }

    // Disabled because context menus aren't Material Design :(
    /*
    @Override
    public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
        int position = ((AdapterContextMenuInfo) menuInfo).position;

        Ringtone ringtone = getRingtone(getRingtoneManagerPosition(position));
        if (ringtone != null && mRingtoneManager.isCustomRingtone(ringtone.getUri())) {
            // It's a custom ringtone so we display the context menu
            menu.setHeaderTitle(ringtone.getTitle(this));
            menu.add(Menu.NONE, Menu.FIRST, Menu.NONE, R.string.delete_ringtone_text);
        }
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case Menu.FIRST: {
                int deletedRingtonePos = ((AdapterContextMenuInfo) item.getMenuInfo()).position;
                Uri deletedRingtoneUri = getRingtone(
                        getRingtoneManagerPosition(deletedRingtonePos)).getUri();
                if(mRingtoneManager.deleteExternalRingtone(deletedRingtoneUri)) {
                    requeryForAdapter();
                } else {
                    Toast.makeText(this, R.string.unable_to_delete_ringtone, Toast.LENGTH_SHORT)
                            .show();
                }
                return true;
            }
            default: {
                return false;
            }
        }
    }
    */

    @Override
    public void onDestroy() {
        if (mCursor != null) {
            mCursor.close();
            mCursor = null;
        }
        super.onDestroy();
    }

    public void onPrepareListView(ListView listView) {
        // Reset the static item count, as this method can be called multiple times
        mStaticItemCount = 0;

        if (mHasDefaultItem) {
            mDefaultRingtonePos = addDefaultRingtoneItem(listView);

            if (getCheckedItem() == POS_UNKNOWN && RingtoneManager.isDefault(mExistingUri)) {
                setCheckedItem(mDefaultRingtonePos);
            }
        }

        if (mHasSilentItem) {
            mSilentPos = addSilentItem(listView);

            // The 'Silent' item should use a null Uri
            if (getCheckedItem() == POS_UNKNOWN && mExistingUri == null) {
                setCheckedItem(mSilentPos);
            }
        }

        if (getCheckedItem() == POS_UNKNOWN) {
            setCheckedItem(getListPosition(mRingtoneManager.getRingtonePosition(mExistingUri)));
        }

        // 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 (!mShowOkCancelButtons) {
            setSuccessResultWithRingtone(getCurrentlySelectedRingtoneUri());
        }
        // If external storage is available, add a button to install sounds from storage.
        if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            addNewSoundItem(listView);
        }

        // Enable context menu in ringtone items
        registerForContextMenu(listView);
    }

    /**
     * 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 sound.
     *
     * This should only need to happen after adding or removing a ringtone.
     */
    private void requeryForAdapter() {
        // Refresh and set a new cursor, closing the old one.
        initRingtoneManager();
        mAdapter.changeCursor(mCursor);

        // Update checked item location.
        int checkedPosition = POS_UNKNOWN;
        for (int i = 0; i < mAdapter.getCount(); i++) {
            if (mAdapter.getItemId(i) == mCheckedItemId) {
                checkedPosition = getListPosition(i);
                break;
            }
        }
        if (mHasSilentItem && checkedPosition == POS_UNKNOWN) {
            checkedPosition = mSilentPos;
        }
        setCheckedItem(checkedPosition);
        setupAlert();
    }

    /**
     * Adds a static item to the top of the list. A static item is one that is not from the
     * RingtoneManager.
     *
     * @param listView The ListView to add to.
     * @param textResId The resource ID of the text for the item.
     * @return The position of the inserted item.
     */
    private int addStaticItem(ListView listView, int textResId) {
        TextView textView = (TextView) getLayoutInflater().inflate(
                com.android.internal.R.layout.select_dialog_singlechoice_material, listView, false);
        textView.setText(textResId);
        listView.addHeaderView(textView);
        mStaticItemCount++;
        return listView.getHeaderViewsCount() - 1;
    }

    private int addDefaultRingtoneItem(ListView listView) {
        if (mType == RingtoneManager.TYPE_NOTIFICATION) {
            return addStaticItem(listView, R.string.notification_sound_default);
        } else if (mType == RingtoneManager.TYPE_ALARM) {
            return addStaticItem(listView, R.string.alarm_sound_default);
        }

        return addStaticItem(listView, R.string.ringtone_default);
    }

    private int addSilentItem(ListView listView) {
        return addStaticItem(listView, com.android.internal.R.string.ringtone_silent);
    }

    private void addNewSoundItem(ListView listView) {
        View view = getLayoutInflater().inflate(R.layout.add_new_sound_item, listView,
                false /* attachToRoot */);
        TextView text = (TextView)view.findViewById(R.id.add_new_sound_text);

        if (mType == RingtoneManager.TYPE_ALARM) {
            text.setText(R.string.add_alarm_text);
        } else if (mType == RingtoneManager.TYPE_NOTIFICATION) {
            text.setText(R.string.add_notification_text);
        } else {
            text.setText(R.string.add_ringtone_text);
        }
        listView.addFooterView(view);
    }

    private void initRingtoneManager() {
        // Reinstantiate the RingtoneManager. Cursor.requery() was deprecated and calling it
        // causes unexpected behavior.
        mRingtoneManager = new RingtoneManager(mTargetContext, /* includeParentRingtones */ true);
        if (mType != -1) {
            mRingtoneManager.setType(mType);
        }
        mCursor = new LocalizedCursor(mRingtoneManager.getCursor(), getResources(), COLUMN_LABEL);
    }

    private Ringtone getRingtone(int ringtoneManagerPosition) {
        if (ringtoneManagerPosition < 0) {
            return null;
        }
        return mRingtoneManager.getRingtone(ringtoneManagerPosition);
    }

    private int getCheckedItem() {
        return mAlertParams.mCheckedItem;
    }

    private void setCheckedItem(int pos) {
        mAlertParams.mCheckedItem = pos;
        mCheckedItemId = mAdapter.getItemId(getRingtoneManagerPosition(pos));
    }

    /*
     * On click of Ok/Cancel buttons
     */
    public void onClick(DialogInterface dialog, int which) {
        boolean positiveResult = which == DialogInterface.BUTTON_POSITIVE;

        // Stop playing the previous ringtone
        mRingtoneManager.stopPreviousRingtone();

        if (positiveResult) {
            setSuccessResultWithRingtone(getCurrentlySelectedRingtoneUri());
        } else {
            setResult(RESULT_CANCELED);
        }

        finish();
    }

    /*
     * On item selected via keys
     */
    public void onItemSelected(AdapterView parent, View view, int position, long id) {
        // footer view
        if (position >= mCursor.getCount() + mStaticItemCount) {
            return;
        }

        playRingtone(position, DELAY_MS_SELECTION_PLAYED);

        // 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 (!mShowOkCancelButtons) {
            setSuccessResultWithRingtone(getCurrentlySelectedRingtoneUri());
        }
    }

    public void onNothingSelected(AdapterView parent) {
    }

    private void playRingtone(int position, int delayMs) {
        mHandler.removeCallbacks(this);
        mSampleRingtonePos = position;
        mHandler.postDelayed(this, delayMs);
    }

    public void run() {
        stopAnyPlayingRingtone();
        if (mSampleRingtonePos == mSilentPos) {
            return;
        }

        Ringtone ringtone;
        if (mSampleRingtonePos == mDefaultRingtonePos) {
            if (mDefaultRingtone == null) {
                mDefaultRingtone = RingtoneManager.getRingtone(this, mUriForDefaultItem);
            }
           /*
            * Stream type of mDefaultRingtone is not set explicitly here.
            * It should be set in accordance with mRingtoneManager of this Activity.
            */
            if (mDefaultRingtone != null) {
                mDefaultRingtone.setStreamType(mRingtoneManager.inferStreamType());
            }
            ringtone = mDefaultRingtone;
            mCurrentRingtone = null;
        } else {
            ringtone = mRingtoneManager.getRingtone(getRingtoneManagerPosition(mSampleRingtonePos));
            mCurrentRingtone = ringtone;
        }

        if (ringtone != null) {
            if (mAttributesFlags != 0) {
                ringtone.setAudioAttributes(
                        new AudioAttributes.Builder(ringtone.getAudioAttributes())
                                .setFlags(mAttributesFlags)
                                .build());
            }
            ringtone.play();
        }
    }

    @Override
    protected void onStop() {
        super.onStop();

        if (!isChangingConfigurations()) {
            stopAnyPlayingRingtone();
        } else {
            saveAnyPlayingRingtone();
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (!isChangingConfigurations()) {
            stopAnyPlayingRingtone();
        }
    }

    private void setSuccessResultWithRingtone(Uri ringtoneUri) {
      setResult(RESULT_OK,
          new Intent().putExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI, ringtoneUri));
    }

    private Uri getCurrentlySelectedRingtoneUri() {
      if (getCheckedItem() == mDefaultRingtonePos) {
        // Use the default Uri that they originally gave us.
        return mUriForDefaultItem;
      } else if (getCheckedItem() == mSilentPos) {
        // Use a null Uri for the 'Silent' item.
        return null;
      } else {
        return mRingtoneManager.getRingtoneUri(getRingtoneManagerPosition(getCheckedItem()));
      }
    }

    private void saveAnyPlayingRingtone() {
        if (mDefaultRingtone != null && mDefaultRingtone.isPlaying()) {
            sPlayingRingtone = mDefaultRingtone;
        } else if (mCurrentRingtone != null && mCurrentRingtone.isPlaying()) {
            sPlayingRingtone = mCurrentRingtone;
        }
    }

    private void stopAnyPlayingRingtone() {
        if (sPlayingRingtone != null && sPlayingRingtone.isPlaying()) {
            sPlayingRingtone.stop();
        }
        sPlayingRingtone = null;

        if (mDefaultRingtone != null && mDefaultRingtone.isPlaying()) {
            mDefaultRingtone.stop();
        }

        if (mRingtoneManager != null) {
            mRingtoneManager.stopPreviousRingtone();
        }
    }

    private int getRingtoneManagerPosition(int listPos) {
        return listPos - mStaticItemCount;
    }

    private int getListPosition(int ringtoneManagerPos) {

        // If the manager position is -1 (for not found), return that
        if (ringtoneManagerPos < 0) return ringtoneManagerPos;

        return ringtoneManagerPos + mStaticItemCount;
    }

    private static class LocalizedCursor extends CursorWrapper {

        final int mTitleIndex;
        final Resources mResources;
        String mNamePrefix;
        final Pattern mSanitizePattern;

        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 {
                try {
                    // Build the prefix for the name of the resource to look up
                    // 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.
                    mNamePrefix = String.format("%s:%s/%s",
                            mResources.getResourcePackageName(R.string.notification_sound_default),
                            mResources.getResourceTypeName(R.string.notification_sound_default),
                            SOUND_NAME_RES_PREFIX);
                } catch (NotFoundException e) {
                    mNamePrefix = null;
                }
            }
        }

        /**
         * Process resource name to generate a valid resource name.
         * @param input
         * @return a non-null String
         */
        private String sanitize(String input) {
            if (input == null) {
                return "";
            }
            return mSanitizePattern.matcher(input).replaceAll("_").toLowerCase();
        }

        @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, false);
            } catch (NotFoundException e) {
                // no localized string, use the default string
                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;
            }
        }
    }

    private class BadgedRingtoneAdapter extends CursorAdapter {
        private final boolean mIsManagedProfile;

        public BadgedRingtoneAdapter(Context context, Cursor cursor, boolean isManagedProfile) {
            super(context, cursor);
            mIsManagedProfile = isManagedProfile;
        }

        @Override
        public long getItemId(int position) {
            if (position < 0) {
                return position;
            }
            return super.getItemId(position);
        }

        @Override
        public View newView(Context context, Cursor cursor, ViewGroup parent) {
            LayoutInflater inflater = LayoutInflater.from(context);
            return inflater.inflate(R.layout.radio_with_work_badge, parent, false);
        }

        @Override
        public void bindView(View view, Context context, Cursor cursor) {
            // Set text as the title of the ringtone
            ((TextView) view.findViewById(R.id.checked_text_view))
                    .setText(cursor.getString(RingtoneManager.TITLE_COLUMN_INDEX));

            boolean isWorkRingtone = false;
            if (mIsManagedProfile) {
                /*
                 * 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 = mRingtoneManager.getRingtoneUri(cursor.getPosition());
                int uriUserId = ContentProvider.getUserIdFromUri(currentUri, mPickerUserId);
                Uri uriWithoutUserId = ContentProvider.getUriWithoutUserId(currentUri);

                if (uriUserId == mPickerUserId && uriWithoutUserId.toString()
                        .startsWith(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI.toString())) {
                    isWorkRingtone = true;
                }
            }

            ImageView workIcon = (ImageView) view.findViewById(R.id.work_icon);
            if(isWorkRingtone) {
                workIcon.setImageDrawable(getPackageManager().getUserBadgeForDensityNoBackground(
                        UserHandle.of(mPickerUserId), -1 /* density */));
                workIcon.setVisibility(View.VISIBLE);
            } else {
                workIcon.setVisibility(View.GONE);
            }
        }
    }
}
