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