• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.systemui;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.content.Context;
22 import android.content.DialogInterface;
23 import android.content.Intent;
24 import android.content.pm.ApplicationInfo;
25 import android.content.pm.PackageManager;
26 import android.net.Uri;
27 import android.os.Bundle;
28 import android.provider.Settings;
29 import android.util.IconDrawableFactory;
30 import android.util.Log;
31 import android.view.LayoutInflater;
32 import android.view.View;
33 import android.view.ViewGroup;
34 import android.widget.AdapterView;
35 import android.widget.ArrayAdapter;
36 import android.widget.ImageView;
37 import android.widget.ListView;
38 import android.widget.TextView;
39 
40 import com.android.internal.app.AlertActivity;
41 import com.android.internal.app.AlertController;
42 import com.android.internal.logging.MetricsLogger;
43 import com.android.internal.logging.nano.MetricsProto;
44 
45 import com.android.systemui.R;
46 
47 import java.util.ArrayList;
48 
49 /**
50  * Show a list of currently running foreground services (supplied by the caller)
51  * that the user can tap through to their application details.
52  */
53 public final class ForegroundServicesDialog extends AlertActivity implements
54         AdapterView.OnItemSelectedListener, DialogInterface.OnClickListener,
55         AlertController.AlertParams.OnPrepareListViewListener {
56 
57     private static final String TAG = "ForegroundServicesDialog";
58 
59     LayoutInflater mInflater;
60 
61     private MetricsLogger mMetricsLogger;
62 
63     private String[] mPackages;
64     private PackageItemAdapter mAdapter;
65 
66     private DialogInterface.OnClickListener mAppClickListener =
67             new DialogInterface.OnClickListener() {
68                 public void onClick(DialogInterface dialog, int which) {
69                     String pkg = mAdapter.getItem(which).packageName;
70                     Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
71                     intent.setData(Uri.fromParts("package", pkg, null));
72                     startActivity(intent);
73                     finish();
74                 }
75             };
76 
77     @Override
onCreate(Bundle savedInstanceState)78     protected void onCreate(Bundle savedInstanceState) {
79         super.onCreate(savedInstanceState);
80         Dependency.initDependencies(getApplicationContext());
81 
82         mMetricsLogger = Dependency.get(MetricsLogger.class);
83 
84         mInflater = LayoutInflater.from(this);
85 
86         mAdapter = new PackageItemAdapter(this);
87 
88         final AlertController.AlertParams p = mAlertParams;
89         p.mAdapter = mAdapter;
90         p.mOnClickListener = mAppClickListener;
91         p.mCustomTitleView = mInflater.inflate(R.layout.foreground_service_title, null);
92         p.mIsSingleChoice = true;
93         p.mOnItemSelectedListener = this;
94         p.mPositiveButtonText = getString(com.android.internal.R.string.done_label);
95         p.mPositiveButtonListener = this;
96         p.mOnPrepareListViewListener = this;
97 
98         updateApps(getIntent());
99         if (mPackages == null) {
100             Log.w(TAG, "No packages supplied");
101             finish();
102             return;
103         }
104 
105         setupAlert();
106     }
107 
108     @Override
onResume()109     protected void onResume() {
110         super.onResume();
111         mMetricsLogger.visible(MetricsProto.MetricsEvent.RUNNING_BACKGROUND_APPS_DIALOG);
112     }
113 
114     @Override
onPause()115     protected void onPause() {
116         super.onPause();
117         mMetricsLogger.hidden(MetricsProto.MetricsEvent.RUNNING_BACKGROUND_APPS_DIALOG);
118     }
119 
120     @Override
onNewIntent(Intent intent)121     protected void onNewIntent(Intent intent) {
122         super.onNewIntent(intent);
123         updateApps(intent);
124     }
125 
126     @Override
onStop()127     protected void onStop() {
128         super.onStop();
129 
130         // This is a transient dialog, if the user leaves it then it goes away,
131         // they can return back to it from the notification.
132         if (!isChangingConfigurations()) {
133             finish();
134         }
135     }
136 
updateApps(Intent intent)137     void updateApps(Intent intent) {
138         mPackages = intent.getStringArrayExtra("packages");
139         if (mPackages != null) {
140             mAdapter.setPackages(mPackages);
141         }
142     }
143 
onPrepareListView(ListView listView)144     public void onPrepareListView(ListView listView) {
145     }
146 
147     /*
148      * On click of Ok/Cancel buttons
149      */
onClick(DialogInterface dialog, int which)150     public void onClick(DialogInterface dialog, int which) {
151         finish();
152     }
153 
onItemSelected(AdapterView parent, View view, int position, long id)154     public void onItemSelected(AdapterView parent, View view, int position, long id) {
155     }
156 
onNothingSelected(AdapterView parent)157     public void onNothingSelected(AdapterView parent) {
158     }
159 
160     static private class PackageItemAdapter extends ArrayAdapter<ApplicationInfo> {
161         final PackageManager mPm;
162         final LayoutInflater mInflater;
163         final IconDrawableFactory mIconDrawableFactory;
164 
PackageItemAdapter(Context context)165         public PackageItemAdapter(Context context) {
166             super(context, R.layout.foreground_service_item);
167             mPm = context.getPackageManager();
168             mInflater = LayoutInflater.from(context);
169             mIconDrawableFactory = IconDrawableFactory.newInstance(context, true);
170         }
171 
setPackages(String[] packages)172         public void setPackages(String[] packages) {
173             clear();
174 
175             ArrayList<ApplicationInfo> apps = new ArrayList<>();
176             for (int i = 0; i < packages.length; i++) {
177                 try {
178                     apps.add(mPm.getApplicationInfo(packages[i],
179                             PackageManager.MATCH_KNOWN_PACKAGES));
180                 } catch (PackageManager.NameNotFoundException e) {
181                 }
182             }
183 
184             apps.sort(new ApplicationInfo.DisplayNameComparator(mPm));
185             addAll(apps);
186         }
187 
188         public @NonNull
getView(int position, @Nullable View convertView, @NonNull ViewGroup parent)189         View getView(int position, @Nullable View convertView,
190                 @NonNull ViewGroup parent) {
191             final View view;
192             if (convertView == null) {
193                 view = mInflater.inflate(R.layout.foreground_service_item, parent, false);
194             } else {
195                 view = convertView;
196             }
197 
198             ImageView icon = view.findViewById(R.id.app_icon);
199             icon.setImageDrawable(mIconDrawableFactory.getBadgedIcon(getItem(position)));
200 
201             TextView label = view.findViewById(R.id.app_name);
202             label.setText(getItem(position).loadLabel(mPm));
203 
204             return view;
205         }
206     }
207 }
208