1 /*
2  * Copyright (C) 2014 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.utils;
18 
19 import android.annotation.Nullable;
20 import android.app.AlertDialog;
21 import android.app.Dialog;
22 import android.app.DialogFragment;
23 import android.content.ComponentName;
24 import android.content.Context;
25 import android.content.DialogInterface;
26 import android.content.pm.PackageItemInfo;
27 import android.content.pm.PackageManager;
28 import android.content.pm.ServiceInfo;
29 import android.os.Bundle;
30 import android.support.v14.preference.SwitchPreference;
31 import android.support.v7.preference.Preference;
32 import android.support.v7.preference.Preference.OnPreferenceChangeListener;
33 import android.support.v7.preference.PreferenceScreen;
34 import android.view.View;
35 import android.widget.TextView;
36 import com.android.settings.R;
37 import com.android.settings.notification.EmptyTextSettings;
38 
39 import java.util.Collections;
40 import java.util.List;
41 
42 public abstract class ManagedServiceSettings extends EmptyTextSettings {
43     private final Config mConfig;
44 
45     protected Context mContext;
46     private PackageManager mPM;
47     protected ServiceListing mServiceListing;
48     private TextView mEmpty;
49 
getConfig()50     abstract protected Config getConfig();
51 
ManagedServiceSettings()52     public ManagedServiceSettings() {
53         mConfig = getConfig();
54     }
55 
56     @Override
onCreate(Bundle icicle)57     public void onCreate(Bundle icicle) {
58         super.onCreate(icicle);
59 
60         mContext = getActivity();
61         mPM = mContext.getPackageManager();
62         mServiceListing = new ServiceListing(mContext, mConfig);
63         mServiceListing.addCallback(new ServiceListing.Callback() {
64             @Override
65             public void onServicesReloaded(List<ServiceInfo> services) {
66                 updateList(services);
67             }
68         });
69         setPreferenceScreen(getPreferenceManager().createPreferenceScreen(mContext));
70     }
71 
72     @Override
onViewCreated(View view, @Nullable Bundle savedInstanceState)73     public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
74         super.onViewCreated(view, savedInstanceState);
75         setEmptyText(mConfig.emptyText);
76     }
77 
78     @Override
onResume()79     public void onResume() {
80         super.onResume();
81         mServiceListing.reload();
82         mServiceListing.setListening(true);
83     }
84 
85     @Override
onPause()86     public void onPause() {
87         super.onPause();
88         mServiceListing.setListening(false);
89     }
90 
updateList(List<ServiceInfo> services)91     private void updateList(List<ServiceInfo> services) {
92         final PreferenceScreen screen = getPreferenceScreen();
93         screen.removeAll();
94         Collections.sort(services, new PackageItemInfo.DisplayNameComparator(mPM));
95         for (ServiceInfo service : services) {
96             final ComponentName cn = new ComponentName(service.packageName, service.name);
97             final String title = service.loadLabel(mPM).toString();
98             final SwitchPreference pref = new SwitchPreference(getPrefContext());
99             pref.setPersistent(false);
100             pref.setIcon(service.loadIcon(mPM));
101             pref.setTitle(title);
102             pref.setChecked(mServiceListing.isEnabled(cn));
103             pref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
104                 @Override
105                 public boolean onPreferenceChange(Preference preference, Object newValue) {
106                     final boolean enable = (boolean) newValue;
107                     return setEnabled(cn, title, enable);
108                 }
109             });
110             screen.addPreference(pref);
111         }
112     }
113 
setEnabled(ComponentName service, String title, boolean enable)114     protected boolean setEnabled(ComponentName service, String title, boolean enable) {
115         if (!enable) {
116             // the simple version: disabling
117             mServiceListing.setEnabled(service, false);
118             return true;
119         } else {
120             if (mServiceListing.isEnabled(service)) {
121                 return true; // already enabled
122             }
123             // show a scary dialog
124             new ScaryWarningDialogFragment()
125                     .setServiceInfo(service, title)
126                     .show(getFragmentManager(), "dialog");
127             return false;
128         }
129     }
130 
131     public class ScaryWarningDialogFragment extends DialogFragment {
132         static final String KEY_COMPONENT = "c";
133         static final String KEY_LABEL = "l";
134 
setServiceInfo(ComponentName cn, String label)135         public ScaryWarningDialogFragment setServiceInfo(ComponentName cn, String label) {
136             Bundle args = new Bundle();
137             args.putString(KEY_COMPONENT, cn.flattenToString());
138             args.putString(KEY_LABEL, label);
139             setArguments(args);
140             return this;
141         }
142 
143         @Override
onCreateDialog(Bundle savedInstanceState)144         public Dialog onCreateDialog(Bundle savedInstanceState) {
145             super.onCreate(savedInstanceState);
146             final Bundle args = getArguments();
147             final String label = args.getString(KEY_LABEL);
148             final ComponentName cn = ComponentName.unflattenFromString(args
149                     .getString(KEY_COMPONENT));
150 
151             final String title = getResources().getString(mConfig.warningDialogTitle, label);
152             final String summary = getResources().getString(mConfig.warningDialogSummary, label);
153             return new AlertDialog.Builder(mContext)
154                     .setMessage(summary)
155                     .setTitle(title)
156                     .setCancelable(true)
157                     .setPositiveButton(R.string.allow,
158                             new DialogInterface.OnClickListener() {
159                                 public void onClick(DialogInterface dialog, int id) {
160                                     mServiceListing.setEnabled(cn, true);
161                                 }
162                             })
163                     .setNegativeButton(R.string.deny,
164                             new DialogInterface.OnClickListener() {
165                                 public void onClick(DialogInterface dialog, int id) {
166                                     // pass
167                                 }
168                             })
169                     .create();
170         }
171     }
172 
173     public static class Config {
174         public String tag;
175         public String setting;
176         public String secondarySetting;
177         public String intentAction;
178         public String permission;
179         public String noun;
180         public int warningDialogTitle;
181         public int warningDialogSummary;
182         public int emptyText;
183     }
184 }
185