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.os.Bundle; 27 import android.text.TextUtils; 28 import android.util.Pair; 29 30 import com.android.internal.logging.nano.MetricsProto.MetricsEvent; 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 onRadioButtonConfirmed(String selectedKey)66 protected void onRadioButtonConfirmed(String selectedKey) { 67 mMetricsFeatureProvider.action(getContext(), 68 MetricsEvent.ACTION_SETTINGS_UPDATE_DEFAULT_APP, 69 selectedKey, 70 Pair.create(MetricsEvent.FIELD_CONTEXT, getMetricsCategory())); 71 72 super.onRadioButtonConfirmed(selectedKey); 73 } 74 75 @Override bindPreferenceExtra(RadioButtonPreference pref, String key, CandidateInfo info, String defaultKey, String systemDefaultKey)76 public void bindPreferenceExtra(RadioButtonPreference pref, 77 String key, CandidateInfo info, String defaultKey, String systemDefaultKey) { 78 if (!(info instanceof DefaultAppInfo)) { 79 return; 80 } 81 if (TextUtils.equals(systemDefaultKey, key)) { 82 pref.setSummary(R.string.system_app); 83 } else if (!TextUtils.isEmpty(((DefaultAppInfo) info).summary)) { 84 pref.setSummary(((DefaultAppInfo) info).summary); 85 } 86 } 87 newConfirmationDialogFragment(String selectedKey, CharSequence confirmationMessage)88 protected ConfirmationDialogFragment newConfirmationDialogFragment(String selectedKey, 89 CharSequence confirmationMessage) { 90 final ConfirmationDialogFragment fragment = new ConfirmationDialogFragment(); 91 fragment.init(this, selectedKey, confirmationMessage); 92 return fragment; 93 } 94 getConfirmationMessage(CandidateInfo info)95 protected CharSequence getConfirmationMessage(CandidateInfo info) { 96 return null; 97 } 98 99 public static class ConfirmationDialogFragment extends InstrumentedDialogFragment 100 implements DialogInterface.OnClickListener { 101 102 public static final String TAG = "DefaultAppConfirm"; 103 public static final String EXTRA_KEY = "extra_key"; 104 public static final String EXTRA_MESSAGE = "extra_message"; 105 106 private DialogInterface.OnClickListener mCancelListener; 107 108 @Override getMetricsCategory()109 public int getMetricsCategory() { 110 return MetricsEvent.DEFAULT_APP_PICKER_CONFIRMATION_DIALOG; 111 } 112 113 /** 114 * Initializes the fragment. 115 * 116 * <p>Should be called after it's constructed. 117 */ init(DefaultAppPickerFragment parent, String key, CharSequence message)118 public void init(DefaultAppPickerFragment parent, String key, CharSequence message) { 119 final Bundle argument = new Bundle(); 120 argument.putString(EXTRA_KEY, key); 121 argument.putCharSequence(EXTRA_MESSAGE, message); 122 setArguments(argument); 123 setTargetFragment(parent, 0); 124 } 125 126 // TODO: add test case for cancelListener setCancelListener(DialogInterface.OnClickListener cancelListener)127 public void setCancelListener(DialogInterface.OnClickListener cancelListener) { 128 this.mCancelListener = cancelListener; 129 } 130 131 @Override onCreateDialog(Bundle savedInstanceState)132 public Dialog onCreateDialog(Bundle savedInstanceState) { 133 final Bundle bundle = getArguments(); 134 final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()) 135 .setMessage(bundle.getCharSequence(EXTRA_MESSAGE)) 136 .setPositiveButton(android.R.string.ok, this) 137 .setNegativeButton(android.R.string.cancel, mCancelListener); 138 return builder.create(); 139 } 140 141 @Override onClick(DialogInterface dialog, int which)142 public void onClick(DialogInterface dialog, int which) { 143 final Fragment fragment = getTargetFragment(); 144 if (fragment instanceof DefaultAppPickerFragment) { 145 final Bundle bundle = getArguments(); 146 ((DefaultAppPickerFragment) fragment).onRadioButtonConfirmed( 147 bundle.getString(EXTRA_KEY)); 148 } 149 } 150 } 151 } 152