146c55104384a9138d51c18c24114885af842afdeJason Monk/* 246c55104384a9138d51c18c24114885af842afdeJason Monk * Copyright (C) 2015 The Android Open Source Project 346c55104384a9138d51c18c24114885af842afdeJason Monk * 446c55104384a9138d51c18c24114885af842afdeJason Monk * Licensed under the Apache License, Version 2.0 (the "License"); 546c55104384a9138d51c18c24114885af842afdeJason Monk * you may not use this file except in compliance with the License. 646c55104384a9138d51c18c24114885af842afdeJason Monk * You may obtain a copy of the License at 746c55104384a9138d51c18c24114885af842afdeJason Monk * 846c55104384a9138d51c18c24114885af842afdeJason Monk * http://www.apache.org/licenses/LICENSE-2.0 946c55104384a9138d51c18c24114885af842afdeJason Monk * 1046c55104384a9138d51c18c24114885af842afdeJason Monk * Unless required by applicable law or agreed to in writing, software 1146c55104384a9138d51c18c24114885af842afdeJason Monk * distributed under the License is distributed on an "AS IS" BASIS, 1246c55104384a9138d51c18c24114885af842afdeJason Monk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1346c55104384a9138d51c18c24114885af842afdeJason Monk * See the License for the specific language governing permissions and 1446c55104384a9138d51c18c24114885af842afdeJason Monk * limitations under the License. 1546c55104384a9138d51c18c24114885af842afdeJason Monk */ 16ef861375eebd9ac6cce7c0bb163380ab1c951063Svetoslavpackage com.android.packageinstaller.permission.ui.television; 1746c55104384a9138d51c18c24114885af842afdeJason Monk 18b22473b280b2b893167ffaae24e9b1c43d343a3fKeyvan Amiriimport android.annotation.Nullable; 19bbc9216d829bf95ea718d430b8b7909c5a259b9bTony Mantlerimport android.app.ActionBar; 20d7f8200201563ca300572e2b56100acfd010140dJason Monkimport android.app.AlertDialog; 2157b5d43f4839c62225cf616296f464b0739e66baTodd Volkertimport android.app.Fragment; 2246c55104384a9138d51c18c24114885af842afdeJason Monkimport android.content.Context; 23d7f8200201563ca300572e2b56100acfd010140dJason Monkimport android.content.DialogInterface; 24d7f8200201563ca300572e2b56100acfd010140dJason Monkimport android.content.DialogInterface.OnClickListener; 2546c55104384a9138d51c18c24114885af842afdeJason Monkimport android.content.Intent; 26bbc9216d829bf95ea718d430b8b7909c5a259b9bTony Mantlerimport android.graphics.drawable.Drawable; 2746c55104384a9138d51c18c24114885af842afdeJason Monkimport android.os.Bundle; 28f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkertimport android.support.v14.preference.SwitchPreference; 2908c441de841e237f93ddb711b8f39f62ee95dddaSvet Ganovimport android.support.v4.util.ArrayMap; 30f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkertimport android.support.v7.preference.Preference; 31f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkertimport android.support.v7.preference.Preference.OnPreferenceChangeListener; 3257b5d43f4839c62225cf616296f464b0739e66baTodd Volkertimport android.support.v7.preference.Preference.OnPreferenceClickListener; 33f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkertimport android.support.v7.preference.PreferenceScreen; 349f0442cdfc055cc3aed19770f48f516b052f6e60Jason Monkimport android.util.ArraySet; 35ae2ceca3c7ac2c3420541f552a2dc47f261ec199Jason Monkimport android.view.Menu; 36ae2ceca3c7ac2c3420541f552a2dc47f261ec199Jason Monkimport android.view.MenuInflater; 3746c55104384a9138d51c18c24114885af842afdeJason Monkimport android.view.MenuItem; 38bbc9216d829bf95ea718d430b8b7909c5a259b9bTony Mantlerimport android.view.View; 39bbc9216d829bf95ea718d430b8b7909c5a259b9bTony Mantlerimport android.view.ViewGroup; 40bbc9216d829bf95ea718d430b8b7909c5a259b9bTony Mantlerimport android.widget.ImageView; 41bbc9216d829bf95ea718d430b8b7909c5a259b9bTony Mantlerimport android.widget.TextView; 4246c55104384a9138d51c18c24114885af842afdeJason Monk 4303dc824d37099b29acb5a0aa28e881d5b05cce0eVinod Krishnanimport com.android.packageinstaller.DeviceUtils; 44bbc9216d829bf95ea718d430b8b7909c5a259b9bTony Mantlerimport com.android.packageinstaller.R; 45267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganovimport com.android.packageinstaller.permission.model.AppPermissionGroup; 46a7a0406958991f7a964370295821d8e477f503e9Svet Ganovimport com.android.packageinstaller.permission.model.PermissionApps; 47a7a0406958991f7a964370295821d8e477f503e9Svet Ganovimport com.android.packageinstaller.permission.model.PermissionApps.Callback; 48a7a0406958991f7a964370295821d8e477f503e9Svet Ganovimport com.android.packageinstaller.permission.model.PermissionApps.PermissionApp; 49dede951ec7d3d7d15b6d82d87cc4407ab96e6357Svet Ganovimport com.android.packageinstaller.permission.ui.ReviewPermissionsActivity; 506dc9e5007de25dd9dd8fd6ebc42d9322069a9a38Jason Monkimport com.android.packageinstaller.permission.utils.LocationUtils; 5108c441de841e237f93ddb711b8f39f62ee95dddaSvet Ganovimport com.android.packageinstaller.permission.utils.SafetyNetLogger; 52f9bf4f795615bac03d1b35a0138318473b1ef6bfSvet Ganovimport com.android.packageinstaller.permission.utils.Utils; 5308c441de841e237f93ddb711b8f39f62ee95dddaSvet Ganov 5408c441de841e237f93ddb711b8f39f62ee95dddaSvet Ganovimport java.util.ArrayList; 5508c441de841e237f93ddb711b8f39f62ee95dddaSvet Ganovimport java.util.List; 5646c55104384a9138d51c18c24114885af842afdeJason Monk 57b22473b280b2b893167ffaae24e9b1c43d343a3fKeyvan Amiripublic final class PermissionAppsFragment extends SettingsWithHeader implements Callback, 58a7a0406958991f7a964370295821d8e477f503e9Svet Ganov OnPreferenceChangeListener { 5946c55104384a9138d51c18c24114885af842afdeJason Monk 60ae2ceca3c7ac2c3420541f552a2dc47f261ec199Jason Monk private static final int MENU_SHOW_SYSTEM = Menu.FIRST; 61ae2ceca3c7ac2c3420541f552a2dc47f261ec199Jason Monk private static final int MENU_HIDE_SYSTEM = Menu.FIRST + 1; 6257b5d43f4839c62225cf616296f464b0739e66baTodd Volkert private static final String KEY_SHOW_SYSTEM_PREFS = "_showSystem"; 63ae2ceca3c7ac2c3420541f552a2dc47f261ec199Jason Monk 64a7a0406958991f7a964370295821d8e477f503e9Svet Ganov public static PermissionAppsFragment newInstance(String permissionName) { 6557b5d43f4839c62225cf616296f464b0739e66baTodd Volkert return setPermissionName(new PermissionAppsFragment(), permissionName); 6657b5d43f4839c62225cf616296f464b0739e66baTodd Volkert } 6757b5d43f4839c62225cf616296f464b0739e66baTodd Volkert 6857b5d43f4839c62225cf616296f464b0739e66baTodd Volkert private static <T extends Fragment> T setPermissionName(T fragment, String permissionName) { 6946c55104384a9138d51c18c24114885af842afdeJason Monk Bundle arguments = new Bundle(); 7046c55104384a9138d51c18c24114885af842afdeJason Monk arguments.putString(Intent.EXTRA_PERMISSION_NAME, permissionName); 7157b5d43f4839c62225cf616296f464b0739e66baTodd Volkert fragment.setArguments(arguments); 7257b5d43f4839c62225cf616296f464b0739e66baTodd Volkert return fragment; 7346c55104384a9138d51c18c24114885af842afdeJason Monk } 7446c55104384a9138d51c18c24114885af842afdeJason Monk 75a7a0406958991f7a964370295821d8e477f503e9Svet Ganov private PermissionApps mPermissionApps; 7646c55104384a9138d51c18c24114885af842afdeJason Monk 7757b5d43f4839c62225cf616296f464b0739e66baTodd Volkert private PreferenceScreen mExtraScreen; 7857b5d43f4839c62225cf616296f464b0739e66baTodd Volkert 79267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov private ArrayMap<String, AppPermissionGroup> mToggledGroups; 809f0442cdfc055cc3aed19770f48f516b052f6e60Jason Monk private ArraySet<String> mLauncherPkgs; 81d7f8200201563ca300572e2b56100acfd010140dJason Monk private boolean mHasConfirmedRevoke; 8208c441de841e237f93ddb711b8f39f62ee95dddaSvet Ganov 83ae2ceca3c7ac2c3420541f552a2dc47f261ec199Jason Monk private boolean mShowSystem; 848321e0fdc7562b08b036c07d7576cba0bf3e644fSvet Ganov private boolean mHasSystemApps; 85ae2ceca3c7ac2c3420541f552a2dc47f261ec199Jason Monk private MenuItem mShowSystemMenu; 86ae2ceca3c7ac2c3420541f552a2dc47f261ec199Jason Monk private MenuItem mHideSystemMenu; 87ae2ceca3c7ac2c3420541f552a2dc47f261ec199Jason Monk 8857b5d43f4839c62225cf616296f464b0739e66baTodd Volkert private Callback mOnPermissionsLoadedListener; 8957b5d43f4839c62225cf616296f464b0739e66baTodd Volkert 9046c55104384a9138d51c18c24114885af842afdeJason Monk @Override 9146c55104384a9138d51c18c24114885af842afdeJason Monk public void onCreate(Bundle savedInstanceState) { 9246c55104384a9138d51c18c24114885af842afdeJason Monk super.onCreate(savedInstanceState); 93a11e73b95ac5d664d57e860fa41a00c7a50720b7Todd Volkert setLoading(true /* loading */, false /* animate */); 9446c55104384a9138d51c18c24114885af842afdeJason Monk setHasOptionsMenu(true); 95bbc9216d829bf95ea718d430b8b7909c5a259b9bTony Mantler final ActionBar ab = getActivity().getActionBar(); 96bbc9216d829bf95ea718d430b8b7909c5a259b9bTony Mantler if (ab != null) { 97bbc9216d829bf95ea718d430b8b7909c5a259b9bTony Mantler ab.setDisplayHomeAsUpEnabled(true); 98bbc9216d829bf95ea718d430b8b7909c5a259b9bTony Mantler } 999f0442cdfc055cc3aed19770f48f516b052f6e60Jason Monk mLauncherPkgs = Utils.getLauncherPackages(getContext()); 10057b5d43f4839c62225cf616296f464b0739e66baTodd Volkert 10157b5d43f4839c62225cf616296f464b0739e66baTodd Volkert String groupName = getArguments().getString(Intent.EXTRA_PERMISSION_NAME); 10257b5d43f4839c62225cf616296f464b0739e66baTodd Volkert mPermissionApps = new PermissionApps(getActivity(), groupName, this); 10357b5d43f4839c62225cf616296f464b0739e66baTodd Volkert mPermissionApps.refresh(true); 10446c55104384a9138d51c18c24114885af842afdeJason Monk } 10546c55104384a9138d51c18c24114885af842afdeJason Monk 10646c55104384a9138d51c18c24114885af842afdeJason Monk @Override 10746c55104384a9138d51c18c24114885af842afdeJason Monk public void onResume() { 10846c55104384a9138d51c18c24114885af842afdeJason Monk super.onResume(); 10993568c580d730911a6e2734e79fbe6dc27c1bca1Jason Monk mPermissionApps.refresh(true); 11046c55104384a9138d51c18c24114885af842afdeJason Monk } 11146c55104384a9138d51c18c24114885af842afdeJason Monk 11246c55104384a9138d51c18c24114885af842afdeJason Monk @Override 113ae2ceca3c7ac2c3420541f552a2dc47f261ec199Jason Monk public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 1148321e0fdc7562b08b036c07d7576cba0bf3e644fSvet Ganov if (mHasSystemApps) { 1158321e0fdc7562b08b036c07d7576cba0bf3e644fSvet Ganov mShowSystemMenu = menu.add(Menu.NONE, MENU_SHOW_SYSTEM, Menu.NONE, 1168321e0fdc7562b08b036c07d7576cba0bf3e644fSvet Ganov R.string.menu_show_system); 1178321e0fdc7562b08b036c07d7576cba0bf3e644fSvet Ganov mHideSystemMenu = menu.add(Menu.NONE, MENU_HIDE_SYSTEM, Menu.NONE, 1188321e0fdc7562b08b036c07d7576cba0bf3e644fSvet Ganov R.string.menu_hide_system); 1198321e0fdc7562b08b036c07d7576cba0bf3e644fSvet Ganov updateMenu(); 1208321e0fdc7562b08b036c07d7576cba0bf3e644fSvet Ganov } 121ae2ceca3c7ac2c3420541f552a2dc47f261ec199Jason Monk } 122ae2ceca3c7ac2c3420541f552a2dc47f261ec199Jason Monk 123ae2ceca3c7ac2c3420541f552a2dc47f261ec199Jason Monk @Override 12446c55104384a9138d51c18c24114885af842afdeJason Monk public boolean onOptionsItemSelected(MenuItem item) { 12546c55104384a9138d51c18c24114885af842afdeJason Monk switch (item.getItemId()) { 12646c55104384a9138d51c18c24114885af842afdeJason Monk case android.R.id.home: 12746c55104384a9138d51c18c24114885af842afdeJason Monk getActivity().finish(); 12846c55104384a9138d51c18c24114885af842afdeJason Monk return true; 129ae2ceca3c7ac2c3420541f552a2dc47f261ec199Jason Monk case MENU_SHOW_SYSTEM: 130ae2ceca3c7ac2c3420541f552a2dc47f261ec199Jason Monk case MENU_HIDE_SYSTEM: 131ae2ceca3c7ac2c3420541f552a2dc47f261ec199Jason Monk mShowSystem = item.getItemId() == MENU_SHOW_SYSTEM; 1325cce11574dc8bd5068b9cc85303c5ab1c1bf38ceJason Monk if (mPermissionApps.getApps() != null) { 1335cce11574dc8bd5068b9cc85303c5ab1c1bf38ceJason Monk onPermissionsLoaded(mPermissionApps); 1345cce11574dc8bd5068b9cc85303c5ab1c1bf38ceJason Monk } 135ae2ceca3c7ac2c3420541f552a2dc47f261ec199Jason Monk updateMenu(); 136ae2ceca3c7ac2c3420541f552a2dc47f261ec199Jason Monk break; 13746c55104384a9138d51c18c24114885af842afdeJason Monk } 13846c55104384a9138d51c18c24114885af842afdeJason Monk return super.onOptionsItemSelected(item); 13946c55104384a9138d51c18c24114885af842afdeJason Monk } 14046c55104384a9138d51c18c24114885af842afdeJason Monk 141ae2ceca3c7ac2c3420541f552a2dc47f261ec199Jason Monk private void updateMenu() { 142ae2ceca3c7ac2c3420541f552a2dc47f261ec199Jason Monk mShowSystemMenu.setVisible(!mShowSystem); 143ae2ceca3c7ac2c3420541f552a2dc47f261ec199Jason Monk mHideSystemMenu.setVisible(mShowSystem); 144ae2ceca3c7ac2c3420541f552a2dc47f261ec199Jason Monk } 145ae2ceca3c7ac2c3420541f552a2dc47f261ec199Jason Monk 146bbc9216d829bf95ea718d430b8b7909c5a259b9bTony Mantler @Override 147f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkert protected void onSetEmptyText(TextView textView) { 148f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkert textView.setText(R.string.no_apps); 149bbc9216d829bf95ea718d430b8b7909c5a259b9bTony Mantler } 150bbc9216d829bf95ea718d430b8b7909c5a259b9bTony Mantler 151bbc9216d829bf95ea718d430b8b7909c5a259b9bTony Mantler @Override 152d9f8f576c98b8ef194ca77131cb779b14dde5886Svet Ganov public void onViewCreated(View view, Bundle savedInstanceState) { 153bbc9216d829bf95ea718d430b8b7909c5a259b9bTony Mantler super.onViewCreated(view, savedInstanceState); 15457b5d43f4839c62225cf616296f464b0739e66baTodd Volkert bindUi(this, mPermissionApps); 155bbc9216d829bf95ea718d430b8b7909c5a259b9bTony Mantler } 156bbc9216d829bf95ea718d430b8b7909c5a259b9bTony Mantler 157b22473b280b2b893167ffaae24e9b1c43d343a3fKeyvan Amiri private static void bindUi(SettingsWithHeader fragment, PermissionApps permissionApps) { 15857b5d43f4839c62225cf616296f464b0739e66baTodd Volkert final Drawable icon = permissionApps.getIcon(); 15957b5d43f4839c62225cf616296f464b0739e66baTodd Volkert final CharSequence label = permissionApps.getLabel(); 160bbc9216d829bf95ea718d430b8b7909c5a259b9bTony Mantler 161b22473b280b2b893167ffaae24e9b1c43d343a3fKeyvan Amiri fragment.setHeader(null, null, null, 162b22473b280b2b893167ffaae24e9b1c43d343a3fKeyvan Amiri fragment.getString(R.string.permission_apps_decor_title, label)); 16346c55104384a9138d51c18c24114885af842afdeJason Monk } 16446c55104384a9138d51c18c24114885af842afdeJason Monk 16557b5d43f4839c62225cf616296f464b0739e66baTodd Volkert private void setOnPermissionsLoadedListener(Callback callback) { 16657b5d43f4839c62225cf616296f464b0739e66baTodd Volkert mOnPermissionsLoadedListener = callback; 16757b5d43f4839c62225cf616296f464b0739e66baTodd Volkert } 16857b5d43f4839c62225cf616296f464b0739e66baTodd Volkert 16946c55104384a9138d51c18c24114885af842afdeJason Monk @Override 17093568c580d730911a6e2734e79fbe6dc27c1bca1Jason Monk public void onPermissionsLoaded(PermissionApps permissionApps) { 171f2736bd4fb3df44ac03385162b9f8d1bf4cb9b61Todd Volkert Context context = getPreferenceManager().getContext(); 172267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov 173267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov if (context == null) { 174267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov return; 175267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov } 176267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov 17703dc824d37099b29acb5a0aa28e881d5b05cce0eVinod Krishnan boolean isTelevision = DeviceUtils.isTelevision(context); 17857b5d43f4839c62225cf616296f464b0739e66baTodd Volkert PreferenceScreen screen = getPreferenceScreen(); 17957b5d43f4839c62225cf616296f464b0739e66baTodd Volkert 18057b5d43f4839c62225cf616296f464b0739e66baTodd Volkert ArraySet<String> preferencesToRemove = new ArraySet<>(); 18157b5d43f4839c62225cf616296f464b0739e66baTodd Volkert for (int i = 0, n = screen.getPreferenceCount(); i < n; i++) { 18257b5d43f4839c62225cf616296f464b0739e66baTodd Volkert preferencesToRemove.add(screen.getPreference(i).getKey()); 18357b5d43f4839c62225cf616296f464b0739e66baTodd Volkert } 18457b5d43f4839c62225cf616296f464b0739e66baTodd Volkert if (mExtraScreen != null) { 18557b5d43f4839c62225cf616296f464b0739e66baTodd Volkert for (int i = 0, n = mExtraScreen.getPreferenceCount(); i < n; i++) { 18657b5d43f4839c62225cf616296f464b0739e66baTodd Volkert preferencesToRemove.add(mExtraScreen.getPreference(i).getKey()); 18757b5d43f4839c62225cf616296f464b0739e66baTodd Volkert } 18857b5d43f4839c62225cf616296f464b0739e66baTodd Volkert } 18957b5d43f4839c62225cf616296f464b0739e66baTodd Volkert 1908321e0fdc7562b08b036c07d7576cba0bf3e644fSvet Ganov mHasSystemApps = false; 1918321e0fdc7562b08b036c07d7576cba0bf3e644fSvet Ganov boolean menuOptionsInvalided = false; 1928321e0fdc7562b08b036c07d7576cba0bf3e644fSvet Ganov 1935cce11574dc8bd5068b9cc85303c5ab1c1bf38ceJason Monk for (PermissionApp app : permissionApps.getApps()) { 19493568c580d730911a6e2734e79fbe6dc27c1bca1Jason Monk if (!Utils.shouldShowPermission(app)) { 1954ef4881c8625437083c4fee36a68b235c5c36b2bSvet Ganov continue; 1964ef4881c8625437083c4fee36a68b235c5c36b2bSvet Ganov } 1974ef4881c8625437083c4fee36a68b235c5c36b2bSvet Ganov 19857b5d43f4839c62225cf616296f464b0739e66baTodd Volkert String key = app.getKey(); 19957b5d43f4839c62225cf616296f464b0739e66baTodd Volkert preferencesToRemove.remove(key); 20057b5d43f4839c62225cf616296f464b0739e66baTodd Volkert Preference existingPref = screen.findPreference(key); 20157b5d43f4839c62225cf616296f464b0739e66baTodd Volkert if (existingPref == null && mExtraScreen != null) { 20257b5d43f4839c62225cf616296f464b0739e66baTodd Volkert existingPref = mExtraScreen.findPreference(key); 20357b5d43f4839c62225cf616296f464b0739e66baTodd Volkert } 20457b5d43f4839c62225cf616296f464b0739e66baTodd Volkert 20557b5d43f4839c62225cf616296f464b0739e66baTodd Volkert boolean isSystemApp = Utils.isSystem(app, mLauncherPkgs); 2068321e0fdc7562b08b036c07d7576cba0bf3e644fSvet Ganov 2078321e0fdc7562b08b036c07d7576cba0bf3e644fSvet Ganov if (isSystemApp && !menuOptionsInvalided) { 2088321e0fdc7562b08b036c07d7576cba0bf3e644fSvet Ganov mHasSystemApps = true; 2098321e0fdc7562b08b036c07d7576cba0bf3e644fSvet Ganov getActivity().invalidateOptionsMenu(); 2108321e0fdc7562b08b036c07d7576cba0bf3e644fSvet Ganov menuOptionsInvalided = true; 2118321e0fdc7562b08b036c07d7576cba0bf3e644fSvet Ganov } 2128321e0fdc7562b08b036c07d7576cba0bf3e644fSvet Ganov 21357b5d43f4839c62225cf616296f464b0739e66baTodd Volkert if (isSystemApp && !isTelevision && !mShowSystem) { 21457b5d43f4839c62225cf616296f464b0739e66baTodd Volkert if (existingPref != null) { 21557b5d43f4839c62225cf616296f464b0739e66baTodd Volkert screen.removePreference(existingPref); 216ae2ceca3c7ac2c3420541f552a2dc47f261ec199Jason Monk } 217ae2ceca3c7ac2c3420541f552a2dc47f261ec199Jason Monk continue; 218ae2ceca3c7ac2c3420541f552a2dc47f261ec199Jason Monk } 21957b5d43f4839c62225cf616296f464b0739e66baTodd Volkert 22057b5d43f4839c62225cf616296f464b0739e66baTodd Volkert if (existingPref != null) { 221acd09293116133b6a86d348e011d8347a03266ecSvetoslav // If existing preference - only update its state. 222acd09293116133b6a86d348e011d8347a03266ecSvetoslav if (app.isPolicyFixed()) { 223acd09293116133b6a86d348e011d8347a03266ecSvetoslav existingPref.setSummary(getString( 224acd09293116133b6a86d348e011d8347a03266ecSvetoslav R.string.permission_summary_enforced_by_policy)); 225acd09293116133b6a86d348e011d8347a03266ecSvetoslav } 226acd09293116133b6a86d348e011d8347a03266ecSvetoslav existingPref.setPersistent(false); 227acd09293116133b6a86d348e011d8347a03266ecSvetoslav existingPref.setEnabled(!app.isPolicyFixed()); 228acd09293116133b6a86d348e011d8347a03266ecSvetoslav if (existingPref instanceof SwitchPreference) { 229acd09293116133b6a86d348e011d8347a03266ecSvetoslav ((SwitchPreference) existingPref) 230acd09293116133b6a86d348e011d8347a03266ecSvetoslav .setChecked(app.areRuntimePermissionsGranted()); 231acd09293116133b6a86d348e011d8347a03266ecSvetoslav } 23257b5d43f4839c62225cf616296f464b0739e66baTodd Volkert continue; 23357b5d43f4839c62225cf616296f464b0739e66baTodd Volkert } 23457b5d43f4839c62225cf616296f464b0739e66baTodd Volkert 23557b5d43f4839c62225cf616296f464b0739e66baTodd Volkert SwitchPreference pref = new SwitchPreference(context); 23657b5d43f4839c62225cf616296f464b0739e66baTodd Volkert pref.setOnPreferenceChangeListener(this); 23757b5d43f4839c62225cf616296f464b0739e66baTodd Volkert pref.setKey(app.getKey()); 23857b5d43f4839c62225cf616296f464b0739e66baTodd Volkert pref.setIcon(app.getIcon()); 23957b5d43f4839c62225cf616296f464b0739e66baTodd Volkert pref.setTitle(app.getLabel()); 24057b5d43f4839c62225cf616296f464b0739e66baTodd Volkert if (app.isPolicyFixed()) { 24157b5d43f4839c62225cf616296f464b0739e66baTodd Volkert pref.setSummary(getString(R.string.permission_summary_enforced_by_policy)); 24257b5d43f4839c62225cf616296f464b0739e66baTodd Volkert } 24357b5d43f4839c62225cf616296f464b0739e66baTodd Volkert pref.setPersistent(false); 24457b5d43f4839c62225cf616296f464b0739e66baTodd Volkert pref.setEnabled(!app.isPolicyFixed()); 24557b5d43f4839c62225cf616296f464b0739e66baTodd Volkert pref.setChecked(app.areRuntimePermissionsGranted()); 24657b5d43f4839c62225cf616296f464b0739e66baTodd Volkert 24757b5d43f4839c62225cf616296f464b0739e66baTodd Volkert if (isSystemApp && isTelevision) { 24857b5d43f4839c62225cf616296f464b0739e66baTodd Volkert if (mExtraScreen == null) { 24957b5d43f4839c62225cf616296f464b0739e66baTodd Volkert mExtraScreen = getPreferenceManager().createPreferenceScreen(context); 25057b5d43f4839c62225cf616296f464b0739e66baTodd Volkert } 25157b5d43f4839c62225cf616296f464b0739e66baTodd Volkert mExtraScreen.addPreference(pref); 25257b5d43f4839c62225cf616296f464b0739e66baTodd Volkert } else { 25357b5d43f4839c62225cf616296f464b0739e66baTodd Volkert screen.addPreference(pref); 25457b5d43f4839c62225cf616296f464b0739e66baTodd Volkert } 25557b5d43f4839c62225cf616296f464b0739e66baTodd Volkert } 25657b5d43f4839c62225cf616296f464b0739e66baTodd Volkert 25757b5d43f4839c62225cf616296f464b0739e66baTodd Volkert if (mExtraScreen != null) { 25857b5d43f4839c62225cf616296f464b0739e66baTodd Volkert preferencesToRemove.remove(KEY_SHOW_SYSTEM_PREFS); 25957b5d43f4839c62225cf616296f464b0739e66baTodd Volkert Preference pref = screen.findPreference(KEY_SHOW_SYSTEM_PREFS); 26057b5d43f4839c62225cf616296f464b0739e66baTodd Volkert 26146c55104384a9138d51c18c24114885af842afdeJason Monk if (pref == null) { 26257b5d43f4839c62225cf616296f464b0739e66baTodd Volkert pref = new Preference(context); 26357b5d43f4839c62225cf616296f464b0739e66baTodd Volkert pref.setKey(KEY_SHOW_SYSTEM_PREFS); 26457b5d43f4839c62225cf616296f464b0739e66baTodd Volkert pref.setIcon(Utils.applyTint(context, R.drawable.ic_toc, 26557b5d43f4839c62225cf616296f464b0739e66baTodd Volkert android.R.attr.colorControlNormal)); 26657b5d43f4839c62225cf616296f464b0739e66baTodd Volkert pref.setTitle(R.string.preference_show_system_apps); 26757b5d43f4839c62225cf616296f464b0739e66baTodd Volkert pref.setOnPreferenceClickListener(new OnPreferenceClickListener() { 26857b5d43f4839c62225cf616296f464b0739e66baTodd Volkert @Override 26957b5d43f4839c62225cf616296f464b0739e66baTodd Volkert public boolean onPreferenceClick(Preference preference) { 27057b5d43f4839c62225cf616296f464b0739e66baTodd Volkert SystemAppsFragment frag = new SystemAppsFragment(); 271bf7316751f0c73b435b693fd20b0c9b2fa973e85Svet Ganov setPermissionName(frag, getArguments().getString( 272bf7316751f0c73b435b693fd20b0c9b2fa973e85Svet Ganov Intent.EXTRA_PERMISSION_NAME)); 27357b5d43f4839c62225cf616296f464b0739e66baTodd Volkert frag.setTargetFragment(PermissionAppsFragment.this, 0); 27457b5d43f4839c62225cf616296f464b0739e66baTodd Volkert getFragmentManager().beginTransaction() 27557b5d43f4839c62225cf616296f464b0739e66baTodd Volkert .replace(android.R.id.content, frag) 27657b5d43f4839c62225cf616296f464b0739e66baTodd Volkert .addToBackStack("SystemApps") 27757b5d43f4839c62225cf616296f464b0739e66baTodd Volkert .commit(); 27857b5d43f4839c62225cf616296f464b0739e66baTodd Volkert return true; 27957b5d43f4839c62225cf616296f464b0739e66baTodd Volkert } 28057b5d43f4839c62225cf616296f464b0739e66baTodd Volkert }); 28157b5d43f4839c62225cf616296f464b0739e66baTodd Volkert screen.addPreference(pref); 28257b5d43f4839c62225cf616296f464b0739e66baTodd Volkert } 28357b5d43f4839c62225cf616296f464b0739e66baTodd Volkert 28457b5d43f4839c62225cf616296f464b0739e66baTodd Volkert int grantedCount = 0; 28557b5d43f4839c62225cf616296f464b0739e66baTodd Volkert for (int i = 0, n = mExtraScreen.getPreferenceCount(); i < n; i++) { 28657b5d43f4839c62225cf616296f464b0739e66baTodd Volkert if (((SwitchPreference) mExtraScreen.getPreference(i)).isChecked()) { 28757b5d43f4839c62225cf616296f464b0739e66baTodd Volkert grantedCount++; 28897dcbacc147a622d267b81b7cc68ff4a5c0c6ddfAlex Chau } 28946c55104384a9138d51c18c24114885af842afdeJason Monk } 29057b5d43f4839c62225cf616296f464b0739e66baTodd Volkert pref.setSummary(getString(R.string.app_permissions_group_summary, 29157b5d43f4839c62225cf616296f464b0739e66baTodd Volkert grantedCount, mExtraScreen.getPreferenceCount())); 29246c55104384a9138d51c18c24114885af842afdeJason Monk } 29357b5d43f4839c62225cf616296f464b0739e66baTodd Volkert 29457b5d43f4839c62225cf616296f464b0739e66baTodd Volkert for (String key : preferencesToRemove) { 29557b5d43f4839c62225cf616296f464b0739e66baTodd Volkert Preference pref = screen.findPreference(key); 29657b5d43f4839c62225cf616296f464b0739e66baTodd Volkert if (pref != null) { 29757b5d43f4839c62225cf616296f464b0739e66baTodd Volkert screen.removePreference(pref); 29857b5d43f4839c62225cf616296f464b0739e66baTodd Volkert } else if (mExtraScreen != null) { 29957b5d43f4839c62225cf616296f464b0739e66baTodd Volkert pref = mExtraScreen.findPreference(key); 30057b5d43f4839c62225cf616296f464b0739e66baTodd Volkert if (pref != null) { 30157b5d43f4839c62225cf616296f464b0739e66baTodd Volkert mExtraScreen.removePreference(pref); 30257b5d43f4839c62225cf616296f464b0739e66baTodd Volkert } 30357b5d43f4839c62225cf616296f464b0739e66baTodd Volkert } 30457b5d43f4839c62225cf616296f464b0739e66baTodd Volkert } 30557b5d43f4839c62225cf616296f464b0739e66baTodd Volkert 306a11e73b95ac5d664d57e860fa41a00c7a50720b7Todd Volkert setLoading(false /* loading */, true /* animate */); 30757b5d43f4839c62225cf616296f464b0739e66baTodd Volkert 30857b5d43f4839c62225cf616296f464b0739e66baTodd Volkert if (mOnPermissionsLoadedListener != null) { 30957b5d43f4839c62225cf616296f464b0739e66baTodd Volkert mOnPermissionsLoadedListener.onPermissionsLoaded(permissionApps); 31057b5d43f4839c62225cf616296f464b0739e66baTodd Volkert } 31146c55104384a9138d51c18c24114885af842afdeJason Monk } 31246c55104384a9138d51c18c24114885af842afdeJason Monk 31346c55104384a9138d51c18c24114885af842afdeJason Monk @Override 314d7f8200201563ca300572e2b56100acfd010140dJason Monk public boolean onPreferenceChange(final Preference preference, Object newValue) { 31546c55104384a9138d51c18c24114885af842afdeJason Monk String pkg = preference.getKey(); 316d7f8200201563ca300572e2b56100acfd010140dJason Monk final PermissionApp app = mPermissionApps.getApp(pkg); 31746c55104384a9138d51c18c24114885af842afdeJason Monk 3186dc9e5007de25dd9dd8fd6ebc42d9322069a9a38Jason Monk if (app == null) { 3196dc9e5007de25dd9dd8fd6ebc42d9322069a9a38Jason Monk return false; 3206dc9e5007de25dd9dd8fd6ebc42d9322069a9a38Jason Monk } 3215c07dcb0698725e7949b030665d21f96c916f3b8Jason Monk 322acd09293116133b6a86d348e011d8347a03266ecSvetoslav if (LocationUtils.isLocationGroupAndProvider(mPermissionApps.getGroupName(), 323acd09293116133b6a86d348e011d8347a03266ecSvetoslav app.getPackageName())) { 3246dc9e5007de25dd9dd8fd6ebc42d9322069a9a38Jason Monk LocationUtils.showLocationDialog(getContext(), app.getLabel()); 32546c55104384a9138d51c18c24114885af842afdeJason Monk return false; 32646c55104384a9138d51c18c24114885af842afdeJason Monk } 327bf7316751f0c73b435b693fd20b0c9b2fa973e85Svet Ganov 328bf7316751f0c73b435b693fd20b0c9b2fa973e85Svet Ganov addToggledGroup(app.getPackageName(), app.getPermissionGroup()); 329bf7316751f0c73b435b693fd20b0c9b2fa973e85Svet Ganov 330bf7316751f0c73b435b693fd20b0c9b2fa973e85Svet Ganov if (app.isReviewRequired()) { 331bf7316751f0c73b435b693fd20b0c9b2fa973e85Svet Ganov Intent intent = new Intent(getActivity(), ReviewPermissionsActivity.class); 332bf7316751f0c73b435b693fd20b0c9b2fa973e85Svet Ganov intent.putExtra(Intent.EXTRA_PACKAGE_NAME, app.getPackageName()); 333bf7316751f0c73b435b693fd20b0c9b2fa973e85Svet Ganov startActivity(intent); 334bf7316751f0c73b435b693fd20b0c9b2fa973e85Svet Ganov return false; 335bf7316751f0c73b435b693fd20b0c9b2fa973e85Svet Ganov } 336bf7316751f0c73b435b693fd20b0c9b2fa973e85Svet Ganov 33746c55104384a9138d51c18c24114885af842afdeJason Monk if (newValue == Boolean.TRUE) { 33846c55104384a9138d51c18c24114885af842afdeJason Monk app.grantRuntimePermissions(); 33946c55104384a9138d51c18c24114885af842afdeJason Monk } else { 340724784b6b90f3d844e807dea1a95c687d592ea27Svet Ganov final boolean grantedByDefault = app.hasGrantedByDefaultPermissions(); 341724784b6b90f3d844e807dea1a95c687d592ea27Svet Ganov if (grantedByDefault || (!app.hasRuntimePermissions() && !mHasConfirmedRevoke)) { 342d7f8200201563ca300572e2b56100acfd010140dJason Monk new AlertDialog.Builder(getContext()) 343724784b6b90f3d844e807dea1a95c687d592ea27Svet Ganov .setMessage(grantedByDefault ? R.string.system_warning 344f193d204d523e400011b0742f3aa8bc5388a4935Jason Monk : R.string.old_sdk_deny_warning) 345d7f8200201563ca300572e2b56100acfd010140dJason Monk .setNegativeButton(R.string.cancel, null) 3463f07e6589d0f036df10d97f676a375b2ce04ae3bSvet Ganov .setPositiveButton(R.string.grant_dialog_button_deny_anyway, 347d7f8200201563ca300572e2b56100acfd010140dJason Monk new OnClickListener() { 348d7f8200201563ca300572e2b56100acfd010140dJason Monk @Override 349d7f8200201563ca300572e2b56100acfd010140dJason Monk public void onClick(DialogInterface dialog, int which) { 350d7f8200201563ca300572e2b56100acfd010140dJason Monk ((SwitchPreference) preference).setChecked(false); 351d7f8200201563ca300572e2b56100acfd010140dJason Monk app.revokeRuntimePermissions(); 352724784b6b90f3d844e807dea1a95c687d592ea27Svet Ganov if (!grantedByDefault) { 353f193d204d523e400011b0742f3aa8bc5388a4935Jason Monk mHasConfirmedRevoke = true; 354f193d204d523e400011b0742f3aa8bc5388a4935Jason Monk } 355d7f8200201563ca300572e2b56100acfd010140dJason Monk } 356d7f8200201563ca300572e2b56100acfd010140dJason Monk }) 357d7f8200201563ca300572e2b56100acfd010140dJason Monk .show(); 358d7f8200201563ca300572e2b56100acfd010140dJason Monk return false; 359d7f8200201563ca300572e2b56100acfd010140dJason Monk } else { 360d7f8200201563ca300572e2b56100acfd010140dJason Monk app.revokeRuntimePermissions(); 361d7f8200201563ca300572e2b56100acfd010140dJason Monk } 36246c55104384a9138d51c18c24114885af842afdeJason Monk } 36346c55104384a9138d51c18c24114885af842afdeJason Monk return true; 36446c55104384a9138d51c18c24114885af842afdeJason Monk } 36546c55104384a9138d51c18c24114885af842afdeJason Monk 36608c441de841e237f93ddb711b8f39f62ee95dddaSvet Ganov @Override 36708c441de841e237f93ddb711b8f39f62ee95dddaSvet Ganov public void onPause() { 36808c441de841e237f93ddb711b8f39f62ee95dddaSvet Ganov super.onPause(); 36908c441de841e237f93ddb711b8f39f62ee95dddaSvet Ganov logToggledGroups(); 37008c441de841e237f93ddb711b8f39f62ee95dddaSvet Ganov } 37108c441de841e237f93ddb711b8f39f62ee95dddaSvet Ganov 372267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov private void addToggledGroup(String packageName, AppPermissionGroup group) { 37308c441de841e237f93ddb711b8f39f62ee95dddaSvet Ganov if (mToggledGroups == null) { 37408c441de841e237f93ddb711b8f39f62ee95dddaSvet Ganov mToggledGroups = new ArrayMap<>(); 37508c441de841e237f93ddb711b8f39f62ee95dddaSvet Ganov } 37608c441de841e237f93ddb711b8f39f62ee95dddaSvet Ganov // Double toggle is back to initial state. 37708c441de841e237f93ddb711b8f39f62ee95dddaSvet Ganov if (mToggledGroups.containsKey(packageName)) { 37808c441de841e237f93ddb711b8f39f62ee95dddaSvet Ganov mToggledGroups.remove(packageName); 37908c441de841e237f93ddb711b8f39f62ee95dddaSvet Ganov } else { 38008c441de841e237f93ddb711b8f39f62ee95dddaSvet Ganov mToggledGroups.put(packageName, group); 38108c441de841e237f93ddb711b8f39f62ee95dddaSvet Ganov } 38208c441de841e237f93ddb711b8f39f62ee95dddaSvet Ganov } 38308c441de841e237f93ddb711b8f39f62ee95dddaSvet Ganov 38408c441de841e237f93ddb711b8f39f62ee95dddaSvet Ganov private void logToggledGroups() { 38508c441de841e237f93ddb711b8f39f62ee95dddaSvet Ganov if (mToggledGroups != null) { 38608c441de841e237f93ddb711b8f39f62ee95dddaSvet Ganov final int groupCount = mToggledGroups.size(); 38708c441de841e237f93ddb711b8f39f62ee95dddaSvet Ganov for (int i = 0; i < groupCount; i++) { 38808c441de841e237f93ddb711b8f39f62ee95dddaSvet Ganov String packageName = mToggledGroups.keyAt(i); 389267c2bd39c248eea2679c0a8efa334d3155e262cSvet Ganov List<AppPermissionGroup> groups = new ArrayList<>(); 39008c441de841e237f93ddb711b8f39f62ee95dddaSvet Ganov groups.add(mToggledGroups.valueAt(i)); 39108c441de841e237f93ddb711b8f39f62ee95dddaSvet Ganov SafetyNetLogger.logPermissionsToggled(packageName, groups); 39208c441de841e237f93ddb711b8f39f62ee95dddaSvet Ganov } 39308c441de841e237f93ddb711b8f39f62ee95dddaSvet Ganov mToggledGroups = null; 39408c441de841e237f93ddb711b8f39f62ee95dddaSvet Ganov } 39508c441de841e237f93ddb711b8f39f62ee95dddaSvet Ganov } 39657b5d43f4839c62225cf616296f464b0739e66baTodd Volkert 397b22473b280b2b893167ffaae24e9b1c43d343a3fKeyvan Amiri public static class SystemAppsFragment extends SettingsWithHeader implements Callback { 39857b5d43f4839c62225cf616296f464b0739e66baTodd Volkert PermissionAppsFragment mOuterFragment; 39957b5d43f4839c62225cf616296f464b0739e66baTodd Volkert 40057b5d43f4839c62225cf616296f464b0739e66baTodd Volkert @Override 40157b5d43f4839c62225cf616296f464b0739e66baTodd Volkert public void onCreate(Bundle savedInstanceState) { 40257b5d43f4839c62225cf616296f464b0739e66baTodd Volkert mOuterFragment = (PermissionAppsFragment) getTargetFragment(); 403a11e73b95ac5d664d57e860fa41a00c7a50720b7Todd Volkert setLoading(true /* loading */, false /* animate */); 40457b5d43f4839c62225cf616296f464b0739e66baTodd Volkert super.onCreate(savedInstanceState); 40557b5d43f4839c62225cf616296f464b0739e66baTodd Volkert } 40657b5d43f4839c62225cf616296f464b0739e66baTodd Volkert 40757b5d43f4839c62225cf616296f464b0739e66baTodd Volkert @Override 40857b5d43f4839c62225cf616296f464b0739e66baTodd Volkert public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { 40957b5d43f4839c62225cf616296f464b0739e66baTodd Volkert if (mOuterFragment.mExtraScreen != null) { 410a11e73b95ac5d664d57e860fa41a00c7a50720b7Todd Volkert setPreferenceScreen(); 41157b5d43f4839c62225cf616296f464b0739e66baTodd Volkert } else { 41257b5d43f4839c62225cf616296f464b0739e66baTodd Volkert mOuterFragment.setOnPermissionsLoadedListener(this); 41357b5d43f4839c62225cf616296f464b0739e66baTodd Volkert } 41457b5d43f4839c62225cf616296f464b0739e66baTodd Volkert } 41557b5d43f4839c62225cf616296f464b0739e66baTodd Volkert 41657b5d43f4839c62225cf616296f464b0739e66baTodd Volkert @Override 417d9f8f576c98b8ef194ca77131cb779b14dde5886Svet Ganov public void onViewCreated(View view, Bundle savedInstanceState) { 41857b5d43f4839c62225cf616296f464b0739e66baTodd Volkert super.onViewCreated(view, savedInstanceState); 41957b5d43f4839c62225cf616296f464b0739e66baTodd Volkert String groupName = getArguments().getString(Intent.EXTRA_PERMISSION_NAME); 42057b5d43f4839c62225cf616296f464b0739e66baTodd Volkert PermissionApps permissionApps = new PermissionApps(getActivity(), groupName, null); 42157b5d43f4839c62225cf616296f464b0739e66baTodd Volkert bindUi(this, permissionApps); 42257b5d43f4839c62225cf616296f464b0739e66baTodd Volkert } 42357b5d43f4839c62225cf616296f464b0739e66baTodd Volkert 42423153df451f163136c7b9f0aefa34c1bc26c7c02Tony Mantler @Override 42523153df451f163136c7b9f0aefa34c1bc26c7c02Tony Mantler public void onResume() { 42623153df451f163136c7b9f0aefa34c1bc26c7c02Tony Mantler super.onResume(); 42723153df451f163136c7b9f0aefa34c1bc26c7c02Tony Mantler mOuterFragment.mPermissionApps.refresh(true); 42823153df451f163136c7b9f0aefa34c1bc26c7c02Tony Mantler } 42923153df451f163136c7b9f0aefa34c1bc26c7c02Tony Mantler 43023153df451f163136c7b9f0aefa34c1bc26c7c02Tony Mantler @Override 43123153df451f163136c7b9f0aefa34c1bc26c7c02Tony Mantler public void onDestroy() { 43223153df451f163136c7b9f0aefa34c1bc26c7c02Tony Mantler super.onDestroy(); 43323153df451f163136c7b9f0aefa34c1bc26c7c02Tony Mantler mOuterFragment.setOnPermissionsLoadedListener(null); 43423153df451f163136c7b9f0aefa34c1bc26c7c02Tony Mantler } 43523153df451f163136c7b9f0aefa34c1bc26c7c02Tony Mantler 436b22473b280b2b893167ffaae24e9b1c43d343a3fKeyvan Amiri 437b22473b280b2b893167ffaae24e9b1c43d343a3fKeyvan Amiri private static void bindUi(SettingsWithHeader fragment, PermissionApps permissionApps) { 438b22473b280b2b893167ffaae24e9b1c43d343a3fKeyvan Amiri final CharSequence label = permissionApps.getLabel(); 439b22473b280b2b893167ffaae24e9b1c43d343a3fKeyvan Amiri fragment.setHeader(null, null, null, 440b22473b280b2b893167ffaae24e9b1c43d343a3fKeyvan Amiri fragment.getString(R.string.system_apps_decor_title, label)); 441b22473b280b2b893167ffaae24e9b1c43d343a3fKeyvan Amiri } 442b22473b280b2b893167ffaae24e9b1c43d343a3fKeyvan Amiri 44357b5d43f4839c62225cf616296f464b0739e66baTodd Volkert @Override 44457b5d43f4839c62225cf616296f464b0739e66baTodd Volkert public void onPermissionsLoaded(PermissionApps permissionApps) { 445a11e73b95ac5d664d57e860fa41a00c7a50720b7Todd Volkert setPreferenceScreen(); 44657b5d43f4839c62225cf616296f464b0739e66baTodd Volkert } 447a11e73b95ac5d664d57e860fa41a00c7a50720b7Todd Volkert 448a11e73b95ac5d664d57e860fa41a00c7a50720b7Todd Volkert private void setPreferenceScreen() { 449a11e73b95ac5d664d57e860fa41a00c7a50720b7Todd Volkert setPreferenceScreen(mOuterFragment.mExtraScreen); 450a11e73b95ac5d664d57e860fa41a00c7a50720b7Todd Volkert setLoading(false /* loading */, true /* animate */); 451a11e73b95ac5d664d57e860fa41a00c7a50720b7Todd Volkert } 45257b5d43f4839c62225cf616296f464b0739e66baTodd Volkert } 45346c55104384a9138d51c18c24114885af842afdeJason Monk} 454