AppPermissionsFragmentWear.java revision a5d853c3bd4e4e84872fc802decd18e9c18408d2
1df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh/*
2df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh* Copyright (C) 2015 The Android Open Source Project
3df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh*
4df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh* Licensed under the Apache License, Version 2.0 (the "License");
5df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh* you may not use this file except in compliance with the License.
6df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh* You may obtain a copy of the License at
7df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh*
8df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh*      http://www.apache.org/licenses/LICENSE-2.0
9df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh*
10df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh* Unless required by applicable law or agreed to in writing, software
11df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh* distributed under the License is distributed on an "AS IS" BASIS,
12df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh* See the License for the specific language governing permissions and
14df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh* limitations under the License.
15df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh*/
16df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh
17df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hughpackage com.android.packageinstaller.permission.ui.wear;
18df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh
190c49c07f1c83e9998fa0af2cd157633644358611Anthony Hughimport android.Manifest;
20df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hughimport android.app.Activity;
21df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hughimport android.app.Fragment;
22df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hughimport android.content.Intent;
23df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hughimport android.content.pm.PackageInfo;
24df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hughimport android.content.pm.PackageManager;
25df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hughimport android.os.Bundle;
26a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwanimport android.preference.Preference;
27a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwanimport android.preference.PreferenceFragment;
28a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwanimport android.preference.SwitchPreference;
29a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwanimport android.support.wearable.view.WearableDialogHelper;
30df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hughimport android.util.Log;
31df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hughimport android.view.LayoutInflater;
32df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hughimport android.view.View;
33df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hughimport android.view.ViewGroup;
34df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hughimport android.widget.Toast;
35df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh
36df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hughimport com.android.packageinstaller.R;
37df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hughimport com.android.packageinstaller.permission.model.AppPermissionGroup;
38df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hughimport com.android.packageinstaller.permission.model.AppPermissions;
39df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hughimport com.android.packageinstaller.permission.utils.LocationUtils;
40df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hughimport com.android.packageinstaller.permission.utils.SafetyNetLogger;
41f9bf4f795615bac03d1b35a0138318473b1ef6bfSvet Ganovimport com.android.packageinstaller.permission.utils.Utils;
42df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh
43df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hughimport java.util.ArrayList;
44df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hughimport java.util.List;
45df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh
46a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwanpublic final class AppPermissionsFragmentWear extends PreferenceFragment {
47a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan    private static final String LOG_TAG = "AppPermFragWear";
48df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh
49a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan    private static final String KEY_NO_PERMISSIONS = "no_permissions";
50df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh
51df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh    public static AppPermissionsFragmentWear newInstance(String packageName) {
52df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh        return setPackageName(new AppPermissionsFragmentWear(), packageName);
53df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh    }
54df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh
55df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh    private static <T extends Fragment> T setPackageName(T fragment, String packageName) {
56df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh        Bundle arguments = new Bundle();
57df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh        arguments.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
58df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh        fragment.setArguments(arguments);
59df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh        return fragment;
60df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh    }
61df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh
62a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan    private List<AppPermissionGroup> mToggledGroups;
63a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan    private AppPermissions mAppPermissions;
64a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan
65a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan    private boolean mHasConfirmedRevoke;
66a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan
67df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh    @Override
68df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh    public void onCreate(Bundle savedInstanceState) {
69df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh        super.onCreate(savedInstanceState);
70df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh
71df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh        String packageName = getArguments().getString(Intent.EXTRA_PACKAGE_NAME);
72df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh        Activity activity = getActivity();
73df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh        PackageManager pm = activity.getPackageManager();
74df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh        PackageInfo packageInfo;
75df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh
76df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh        try {
77df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh            packageInfo = pm.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS);
78df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh        } catch (PackageManager.NameNotFoundException e) {
79df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh            Log.i(LOG_TAG, "No package:" + activity.getCallingPackage(), e);
80df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh            packageInfo = null;
81df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh        }
82df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh
83df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh        if (packageInfo == null) {
84df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh            Toast.makeText(activity, R.string.app_not_found_dlg_title, Toast.LENGTH_LONG).show();
85df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh            activity.finish();
86df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh            return;
87df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh        }
88df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh
89a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan        mAppPermissions = new AppPermissions(
90a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan                activity, packageInfo, null, true, () -> getActivity().finish());
91df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh
92a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan        addPreferencesFromResource(R.xml.watch_permissions);
93df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh        initializePermissionGroupList();
94df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh    }
95df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh
96df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh    @Override
97df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh    public void onResume() {
98df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh        super.onResume();
99df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh        mAppPermissions.refresh();
100df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh
101df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh        // Also refresh the UI
102a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan        for (final AppPermissionGroup group : mAppPermissions.getPermissionGroups()) {
103a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan            Preference pref = findPreference(group.getName());
104a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan            if (pref instanceof SwitchPreference) {
105a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan                ((SwitchPreference) pref).setChecked(group.areRuntimePermissionsGranted());
106a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan            }
107df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh        }
108df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh    }
109df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh
110df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh    @Override
111a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan    public void onPause() {
112a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan        super.onPause();
113a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan        logAndClearToggledGroups();
114df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh    }
115df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh
116df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh    private void initializePermissionGroupList() {
117df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh        final String packageName = mAppPermissions.getPackageInfo().packageName;
118df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh        List<AppPermissionGroup> groups = mAppPermissions.getPermissionGroups();
119a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan        List<SwitchPreference> nonSystemGroups = new ArrayList<>();
120a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan
121a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan        if (!groups.isEmpty()) {
122a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan            getPreferenceScreen().removePreference(findPreference(KEY_NO_PERMISSIONS));
123a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan        }
124736c82ba577f8f972ea4277357ae440b192dcd13Anthony Hugh
125a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan        for (final AppPermissionGroup group : groups) {
126df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh            if (!Utils.shouldShowPermission(group, packageName)) {
127df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh                continue;
128df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh            }
129df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh
130736c82ba577f8f972ea4277357ae440b192dcd13Anthony Hugh            boolean isPlatform = group.getDeclaringPackage().equals(Utils.OS_PKG);
131736c82ba577f8f972ea4277357ae440b192dcd13Anthony Hugh
132a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan            final SwitchPreference pref = new SwitchPreference(getContext());
133a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan            pref.setKey(group.getName());
134a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan            pref.setTitle(group.getLabel());
135a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan            pref.setChecked(group.areRuntimePermissionsGranted());
136a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan
137a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan            if (group.isPolicyFixed()) {
138a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan                pref.setEnabled(false);
139a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan            } else {
140a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan                pref.setOnPreferenceChangeListener((p, newVal) -> {
141a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan                    if (LocationUtils.isLocationGroupAndProvider(
142a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan                            group.getName(), group.getApp().packageName)) {
143a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan                        LocationUtils.showLocationDialog(
144a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan                                getContext(), mAppPermissions.getAppLabel());
145a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan                        return false;
146a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan                    }
147a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan
148a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan                    if ((Boolean) newVal) {
149a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan                        setPermission(group, pref, true);
150a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan                    } else {
151a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan                        final boolean grantedByDefault = group.hasGrantedByDefaultPermission();
152a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan                        if (grantedByDefault
153a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan                                || (!group.hasRuntimePermission() && !mHasConfirmedRevoke)) {
154a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan                            new WearableDialogHelper.DialogBuilder(getContext())
155a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan                                    .setNegativeIcon(R.drawable.confirm_button)
156a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan                                    .setPositiveIcon(R.drawable.cancel_button)
157a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan                                    .setNegativeButton(R.string.grant_dialog_button_deny_anyway,
158a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan                                            (dialog, which) -> {
159a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan                                                setPermission(group, pref, false);
160a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan                                                if (!group.hasGrantedByDefaultPermission()) {
161a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan                                                    mHasConfirmedRevoke = true;
162a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan                                                }
163a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan                                            })
164a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan                                    .setPositiveButton(R.string.cancel, (dialog, which) -> {})
165a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan                                    .setMessage(grantedByDefault ?
166a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan                                            R.string.system_warning : R.string.old_sdk_deny_warning)
167a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan                                    .show();
168a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan                            return false;
169a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan                        } else {
170a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan                            setPermission(group, pref, false);
171a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan                        }
172a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan                    }
173a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan
174a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan                    return true;
175a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan                });
176a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan            }
177736c82ba577f8f972ea4277357ae440b192dcd13Anthony Hugh
178736c82ba577f8f972ea4277357ae440b192dcd13Anthony Hugh            // The UI shows System settings first, then non-system settings
179736c82ba577f8f972ea4277357ae440b192dcd13Anthony Hugh            if (isPlatform) {
180a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan                getPreferenceScreen().addPreference(pref);
181736c82ba577f8f972ea4277357ae440b192dcd13Anthony Hugh            } else {
182a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan                nonSystemGroups.add(pref);
183736c82ba577f8f972ea4277357ae440b192dcd13Anthony Hugh            }
184736c82ba577f8f972ea4277357ae440b192dcd13Anthony Hugh        }
185736c82ba577f8f972ea4277357ae440b192dcd13Anthony Hugh
186736c82ba577f8f972ea4277357ae440b192dcd13Anthony Hugh        // Now add the non-system settings to the end of the list
187a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan        for (SwitchPreference nonSystemGroup : nonSystemGroups) {
188a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan            getPreferenceScreen().addPreference(nonSystemGroup);
189df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh        }
190df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh    }
191df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh
192a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan    private void setPermission(AppPermissionGroup group, SwitchPreference pref, boolean grant) {
193a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan        if (grant) {
194df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh            group.grantRuntimePermissions(false);
195df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh        } else {
196a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan            group.revokeRuntimePermissions(false);
1974b7427563d334dab50eb77028a78e709ea58880bAnthony Hugh        }
198a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan        addToggledGroup(group);
199a5d853c3bd4e4e84872fc802decd18e9c18408d2Michael Kwan        pref.setChecked(grant);
200df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh    }
201df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh
202df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh    private void addToggledGroup(AppPermissionGroup group) {
203df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh        if (mToggledGroups == null) {
204df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh            mToggledGroups = new ArrayList<>();
205df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh        }
206df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh        // Double toggle is back to initial state.
207df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh        if (mToggledGroups.contains(group)) {
208df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh            mToggledGroups.remove(group);
209df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh        } else {
210df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh            mToggledGroups.add(group);
211df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh        }
212df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh    }
213df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh
214736c82ba577f8f972ea4277357ae440b192dcd13Anthony Hugh    private void logAndClearToggledGroups() {
215df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh        if (mToggledGroups != null) {
216df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh            String packageName = mAppPermissions.getPackageInfo().packageName;
217df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh            SafetyNetLogger.logPermissionsToggled(packageName, mToggledGroups);
218df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh            mToggledGroups = null;
219df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh        }
220df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh    }
221df4d4542c2cf2fa0a7539412af2a99d60b1c2a15Anthony Hugh}
222