1 /* 2 * Copyright (C) 2017 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.settings.applications.defaultapps; 18 19 import android.app.Activity; 20 import android.app.AlertDialog; 21 import android.app.Dialog; 22 import android.app.DialogFragment; 23 import android.app.Fragment; 24 import android.content.Context; 25 import android.content.DialogInterface; 26 import android.content.DialogInterface.OnClickListener; 27 import android.os.Bundle; 28 import android.text.TextUtils; 29 30 import com.android.internal.logging.nano.MetricsProto; 31 import com.android.settings.R; 32 import com.android.settings.applications.PackageManagerWrapper; 33 import com.android.settings.applications.PackageManagerWrapperImpl; 34 import com.android.settings.core.instrumentation.InstrumentedDialogFragment; 35 import com.android.settings.widget.RadioButtonPickerFragment; 36 import com.android.settings.widget.RadioButtonPreference; 37 38 /** 39 * A generic app picker fragment that shows a list of app as radio button group. 40 */ 41 public abstract class DefaultAppPickerFragment extends RadioButtonPickerFragment { 42 43 protected PackageManagerWrapper mPm; 44 45 @Override onAttach(Context context)46 public void onAttach(Context context) { 47 super.onAttach(context); 48 mPm = new PackageManagerWrapperImpl(context.getPackageManager()); 49 } 50 51 @Override onRadioButtonClicked(RadioButtonPreference selected)52 public void onRadioButtonClicked(RadioButtonPreference selected) { 53 final String selectedKey = selected.getKey(); 54 final CharSequence confirmationMessage = getConfirmationMessage(getCandidate(selectedKey)); 55 final Activity activity = getActivity(); 56 if (TextUtils.isEmpty(confirmationMessage)) { 57 super.onRadioButtonClicked(selected); 58 } else if (activity != null) { 59 final DialogFragment fragment = 60 newConfirmationDialogFragment(selectedKey, confirmationMessage); 61 fragment.show(activity.getFragmentManager(), ConfirmationDialogFragment.TAG); 62 } 63 } 64 65 @Override bindPreferenceExtra(RadioButtonPreference pref, String key, CandidateInfo info, String defaultKey, String systemDefaultKey)66 public void bindPreferenceExtra(RadioButtonPreference pref, 67 String key, CandidateInfo info, String defaultKey, String systemDefaultKey) { 68 if (!(info instanceof DefaultAppInfo)) { 69 return; 70 } 71 if (TextUtils.equals(systemDefaultKey, key)) { 72 pref.setSummary(R.string.system_app); 73 } else if (!TextUtils.isEmpty(((DefaultAppInfo) info).summary)) { 74 pref.setSummary(((DefaultAppInfo) info).summary); 75 } 76 } 77 newConfirmationDialogFragment(String selectedKey, CharSequence confirmationMessage)78 protected ConfirmationDialogFragment newConfirmationDialogFragment(String selectedKey, 79 CharSequence confirmationMessage) { 80 final ConfirmationDialogFragment fragment = new ConfirmationDialogFragment(); 81 fragment.init(this, selectedKey, confirmationMessage); 82 return fragment; 83 } 84 getConfirmationMessage(CandidateInfo info)85 protected CharSequence getConfirmationMessage(CandidateInfo info) { 86 return null; 87 } 88 89 public static class ConfirmationDialogFragment extends InstrumentedDialogFragment 90 implements DialogInterface.OnClickListener { 91 92 public static final String TAG = "DefaultAppConfirm"; 93 public static final String EXTRA_KEY = "extra_key"; 94 public static final String EXTRA_MESSAGE = "extra_message"; 95 96 private DialogInterface.OnClickListener mCancelListener; 97 98 @Override getMetricsCategory()99 public int getMetricsCategory() { 100 return MetricsProto.MetricsEvent.DEFAULT_APP_PICKER_CONFIRMATION_DIALOG; 101 } 102 103 /** 104 * Initializes the fragment. 105 * 106 * <p>Should be called after it's constructed. 107 */ init(DefaultAppPickerFragment parent, String key, CharSequence message)108 public void init(DefaultAppPickerFragment parent, String key, CharSequence message) { 109 final Bundle argument = new Bundle(); 110 argument.putString(EXTRA_KEY, key); 111 argument.putCharSequence(EXTRA_MESSAGE, message); 112 setArguments(argument); 113 setTargetFragment(parent, 0); 114 } 115 116 // TODO: add test case for cancelListener setCancelListener(DialogInterface.OnClickListener cancelListener)117 public void setCancelListener(DialogInterface.OnClickListener cancelListener) { 118 this.mCancelListener = cancelListener; 119 } 120 121 @Override onCreateDialog(Bundle savedInstanceState)122 public Dialog onCreateDialog(Bundle savedInstanceState) { 123 final Bundle bundle = getArguments(); 124 final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()) 125 .setMessage(bundle.getCharSequence(EXTRA_MESSAGE)) 126 .setPositiveButton(android.R.string.ok, this) 127 .setNegativeButton(android.R.string.cancel, mCancelListener); 128 return builder.create(); 129 } 130 131 @Override onClick(DialogInterface dialog, int which)132 public void onClick(DialogInterface dialog, int which) { 133 final Fragment fragment = getTargetFragment(); 134 if (fragment instanceof DefaultAppPickerFragment) { 135 final Bundle bundle = getArguments(); 136 ((DefaultAppPickerFragment) fragment).onRadioButtonConfirmed( 137 bundle.getString(EXTRA_KEY)); 138 } 139 } 140 } 141 } 142