blob: 38a899b03e0f8efd3e99a48b0f52409e6bd7d907 [file] [log] [blame]
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.permissioncontroller.permission.ui.television;
import static com.android.permissioncontroller.permission.ui.television.DebugConfig.DEBUG;
import static com.android.permissioncontroller.permission.ui.television.DebugConfig.TAG;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.ViewModelProvider;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.permissioncontroller.R;
import com.android.permissioncontroller.permission.model.livedatatypes.PermGroupPackagesUiInfo;
import com.android.permissioncontroller.permission.ui.model.ManagePermissionsViewModel;
import com.android.permissioncontroller.permission.ui.model.PermissionGroupPreferenceUtils;
import com.android.permissioncontroller.permission.utils.Utils;
import java.util.List;
/**
* The {@link androidx.fragment.app.Fragment} that represents the "main" screen of the
* PermissionController application.
* It lists the most relevant permission groups and contains a link to a different screen that lists
* the other permission groups - {@link ManagePermissionsOtherFragment}.
* It relies on the {@link ManagePermissionsViewModel} to for the data loading, maintaining and
* monitoring for changes.
*/
public final class ManagePermissionsFragment extends SettingsWithHeader {
private static final String KEY_OTHER_PERMISSIONS = "other_permissions";
private ManagePermissionsViewModel mViewModel;
/**
* @return a new instance of {@link ManagePermissionsFragment}.
*/
public static ManagePermissionsFragment newInstance() {
return new ManagePermissionsFragment();
}
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
final FragmentActivity activity = requireActivity();
final ViewModelProvider.Factory viewModelFactory =
ViewModelProvider.AndroidViewModelFactory.getInstance(activity.getApplication());
mViewModel = new ViewModelProvider(activity, viewModelFactory)
.get(ManagePermissionsViewModel.class);
if (DEBUG) {
Log.d(TAG, "ManagePermissionsFragment.onCreate()\n viewModel=" + mViewModel);
}
mViewModel.getUsedPermissionGroups().observe(this, this::onPermissionGroupsChanged);
}
@Override
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
final String title = getString(R.string.manage_permissions_decor_title);
setHeader(null, null, null, title);
}
private void onPermissionGroupsChanged(List<PermGroupPackagesUiInfo> permissionGroups) {
final Context context = getPreferenceManager().getContext();
if (context == null) {
return;
}
final PreferenceScreen screen = getPreferenceScreen();
// First check if "Other preferences" button exists. If it does: remove it, but hold on to
// the reference - we'll it add back later, after the preferences for the permission groups
// have been updated. If it does not exist: create and hold on to it.
Preference otherPermissionsPreference = screen.findPreference(KEY_OTHER_PERMISSIONS);
if (otherPermissionsPreference == null) {
otherPermissionsPreference = buildOtherPermissionsPreference(context);
} else {
screen.removePreference(otherPermissionsPreference);
// The PreferenceScreen is ordering items as added
// (see PreferenceGroup#setOrderingAsAdded()), which means that it assigns positional
// indexes ("order") to Preferences incrementally as they are added, BUT ONLY IF their
// current "order" is the DEFAULT_ORDER.
// However, when the Preferences are removed from the group they keep their "order" and
// thus when they are re-added to a group (same or another) their "order" does not get
// re-assigned, so they may show up at the position they previously were at.
// We want the otherPermissionsPreference to always be the last in the list, so reset
// its "order" to DEFAULT, so that we add last to the group, it indeed goes into the
// last position.
otherPermissionsPreference.setOrder(Preference.DEFAULT_ORDER);
}
PermissionGroupPreferenceUtils.updateGroupOfPermissionPreferences(context, screen,
permissionGroups);
screen.addPreference(otherPermissionsPreference);
}
private Preference buildOtherPermissionsPreference(Context context) {
final Preference preference = new Preference(context);
preference.setPersistent(false);
preference.setKey(KEY_OTHER_PERMISSIONS);
preference.setTitle(R.string.other_permissions_label);
preference.setIcon(
Utils.applyTint(
context, R.drawable.ic_more_items, android.R.attr.colorControlNormal));
preference.setOnPreferenceClickListener(p -> {
getParentFragmentManager().beginTransaction()
.replace(android.R.id.content, ManagePermissionsOtherFragment.newInstance())
.addToBackStack(null)
.commit();
return true;
});
// Make invisible for now and subscribe to the LiveData that tracks whether there are any
// unused or additional permissions.
preference.setVisible(false);
mViewModel.hasUnusedOrAdditionalPermissionGroups().observe(this, preference::setVisible);
return preference;
}
}