• 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.packageinstaller.permission.ui.auto;
18 
19 
20 import android.app.Activity;
21 import android.app.AlertDialog;
22 import android.app.Fragment;
23 import android.content.Context;
24 import android.content.Intent;
25 import android.content.pm.PackageInfo;
26 import android.content.pm.PackageManager;
27 import android.os.Bundle;
28 import android.support.annotation.DrawableRes;
29 import android.util.Log;
30 import android.view.LayoutInflater;
31 import android.view.MotionEvent;
32 import android.view.View;
33 import android.view.ViewGroup;
34 import android.widget.Switch;
35 import android.widget.Toast;
36 
37 import com.android.car.list.IconToggleLineItem;
38 import com.android.car.list.TypedPagedListAdapter;
39 import com.android.packageinstaller.R;
40 import com.android.packageinstaller.permission.model.AppPermissionGroup;
41 import com.android.packageinstaller.permission.model.AppPermissions;
42 import com.android.packageinstaller.permission.utils.Utils;
43 
44 import java.util.ArrayList;
45 
46 import androidx.car.widget.PagedListView;
47 
48 /**
49  * Contains all permissions in a list for a given application.
50  */
51 public final class AppPermissionsFragment extends Fragment{
52 
53     private static final String LOG_TAG = "ManagePermsFragment";
54     public static final String EXTRA_LAYOUT = "extra_layout";
55 
56     private AppPermissions mAppPermissions;
57 
58     private String mPackageName;
59 
60     protected PagedListView mListView;
61     protected TypedPagedListAdapter mPagedListAdapter;
62 
63 
64     /**
65      * Creates a new instance.
66      * @param packageName the packageName of the application that we are listing the
67      *                    permissions here.
68      */
newInstance(String packageName)69     public static AppPermissionsFragment newInstance(String packageName) {
70         AppPermissionsFragment fragment = new AppPermissionsFragment();
71         Bundle arguments = new Bundle();
72         arguments.putInt(EXTRA_LAYOUT, R.layout.car_app_permissions);
73         arguments.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
74         fragment.setArguments(arguments);
75         return fragment;
76     }
77 
78     @Override
onActivityCreated(Bundle savedInstanceState)79     public void onActivityCreated(Bundle savedInstanceState) {
80         super.onActivityCreated(savedInstanceState);
81         getView().findViewById(R.id.action_bar_icon_container).setOnClickListener(
82                 v -> getActivity().onBackPressed());
83 
84         mListView = (PagedListView) getView().findViewById(R.id.list);
85         mPagedListAdapter = new TypedPagedListAdapter(getLineItems());
86         mListView.setAdapter(mPagedListAdapter);
87     }
88 
notifyDataSetChanged()89     protected void notifyDataSetChanged() {
90         mPagedListAdapter.notifyDataSetChanged();
91     }
92 
93     @Override
onCreate(Bundle savedInstanceState)94     public void onCreate(Bundle savedInstanceState) {
95         super.onCreate(savedInstanceState);
96         if (savedInstanceState != null
97                 && savedInstanceState.containsKey(Intent.EXTRA_PACKAGE_NAME)) {
98             mPackageName = savedInstanceState.getString(Intent.EXTRA_PACKAGE_NAME);
99         } else if (getArguments() != null
100                 && getArguments().containsKey(Intent.EXTRA_PACKAGE_NAME)) {
101             mPackageName = getArguments().getString(Intent.EXTRA_PACKAGE_NAME);
102         }
103 
104         if (mPackageName == null) {
105             Log.e(LOG_TAG, "package name is missing");
106             return;
107         }
108         Activity activity = getActivity();
109         PackageInfo packageInfo = getPackageInfo(activity, mPackageName);
110         if (packageInfo == null) {
111             Toast.makeText(activity, R.string.app_not_found_dlg_title, Toast.LENGTH_LONG).show();
112             activity.finish();
113             return;
114         }
115 
116         mAppPermissions = new AppPermissions(activity, packageInfo, null, true, new Runnable() {
117             @Override
118             public void run() {
119                 activity.finish();
120             }
121         });
122     }
123 
124     @Override
onSaveInstanceState(Bundle outState)125     public void onSaveInstanceState(Bundle outState) {
126         super.onSaveInstanceState(outState);
127         outState.putString(Intent.EXTRA_PACKAGE_NAME, mPackageName);
128     }
129 
130     @Override
onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)131     public View onCreateView(LayoutInflater inflater, ViewGroup container,
132             Bundle savedInstanceState) {
133         return inflater.inflate(getArguments().getInt(EXTRA_LAYOUT), container, false);
134     }
135 
136     @Override
onResume()137     public void onResume() {
138         super.onResume();
139         mAppPermissions.refresh();
140     }
141 
142     /**
143      * Gets the list of the LineItems to show up in the list
144      */
getLineItems()145     public ArrayList<TypedPagedListAdapter.LineItem> getLineItems() {
146         ArrayList<TypedPagedListAdapter.LineItem> items = new ArrayList<>();
147         Context context = getContext();
148         if (context == null) {
149             return items;
150         }
151 
152         for (AppPermissionGroup group : mAppPermissions.getPermissionGroups()) {
153             if (!Utils.shouldShowPermission(group, mAppPermissions.getPackageInfo().packageName)) {
154                 continue;
155             }
156             items.add(new PermissionLineItem(group, context));
157         }
158         return items;
159     }
160 
getPackageInfo(Activity activity, String packageName)161     private static PackageInfo getPackageInfo(Activity activity, String packageName) {
162         try {
163             return activity.getPackageManager().getPackageInfo(
164                     packageName, PackageManager.GET_PERMISSIONS);
165         } catch (PackageManager.NameNotFoundException e) {
166             if (Log.isLoggable(LOG_TAG, Log.INFO)) {
167                 Log.i(LOG_TAG, "No package:" + activity.getCallingPackage(), e);
168             }
169             return null;
170         }
171     }
172 
173     private class PermissionLineItem extends IconToggleLineItem {
174         private final AppPermissionGroup mPermissionGroup;
175         private final Context mContext;
176 
PermissionLineItem(AppPermissionGroup permissionGroup, Context context)177         PermissionLineItem(AppPermissionGroup permissionGroup, Context context) {
178             super(permissionGroup.getLabel(), context);
179             mContext = context;
180             mPermissionGroup = permissionGroup;
181         }
182 
183         @Override
onToggleTouched(Switch toggleSwitch, MotionEvent event)184         public boolean onToggleTouched(Switch toggleSwitch, MotionEvent event) {
185             if (event.getAction() != MotionEvent.ACTION_DOWN) {
186                 return true;
187             }
188             if (!isChecked()) {
189                 mPermissionGroup.grantRuntimePermissions(false);
190                 toggleSwitch.performClick();
191             } else {
192                 final boolean grantedByDefault =
193                         mPermissionGroup.hasGrantedByDefaultPermission();
194                 if (grantedByDefault || !mPermissionGroup.doesSupportRuntimePermissions()) {
195                     new AlertDialog.Builder(mContext)
196                             .setMessage(grantedByDefault
197                                     ? R.string.system_warning : R.string.old_sdk_deny_warning)
198                             .setNegativeButton(R.string.cancel, null /* listener */)
199                             .setPositiveButton(R.string.grant_dialog_button_deny_anyway,
200                                     (dialog, which) -> {
201                                         mPermissionGroup.revokeRuntimePermissions(false);
202                                         toggleSwitch.performClick();
203                                     })
204                             .show();
205                 } else {
206                     mPermissionGroup.revokeRuntimePermissions(false);
207                     toggleSwitch.performClick();
208                 }
209             }
210             return true;
211         }
212 
213         @DrawableRes
getIcon()214         public int getIcon() {
215             return mPermissionGroup.getIconResId();
216         }
217 
218         @Override
isChecked()219         public boolean isChecked() {
220             return mPermissionGroup.areRuntimePermissionsGranted();
221         }
222 
223         @Override
getDesc()224         public CharSequence getDesc() {
225             return null;
226         }
227 
228         @Override
isEnabled()229         public boolean isEnabled() {
230             return true;
231         }
232 
233         @Override
isExpandable()234         public boolean isExpandable() {
235             return false;
236         }
237     }
238 }
239