blob: db1c94d8c7591d38f6e5bfd118414dc91fc8aeaf [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.packageinstaller.permission.ui.wear;
import android.Manifest;
import android.app.Activity;
import android.app.Fragment;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.wearable.view.WearableListView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import com.android.packageinstaller.R;
import com.android.packageinstaller.permission.model.AppPermissionGroup;
import com.android.packageinstaller.permission.model.AppPermissions;
import com.android.packageinstaller.permission.ui.wear.settings.PermissionsSettingsAdapter;
import com.android.packageinstaller.permission.ui.wear.settings.SettingsAdapter;
import com.android.packageinstaller.permission.utils.LocationUtils;
import com.android.packageinstaller.permission.utils.SafetyNetLogger;
import com.android.packageinstaller.permission.utils.Utils;
import java.util.ArrayList;
import java.util.List;
public final class AppPermissionsFragmentWear extends TitledSettingsFragment {
private static final String LOG_TAG = "ManagePermsFragment";
private static final int WARNING_CONFIRMATION_REQUEST = 252;
private List<AppPermissionGroup> mToggledGroups;
private AppPermissions mAppPermissions;
private PermissionsSettingsAdapter mAdapter;
private boolean mHasConfirmedRevoke;
public static AppPermissionsFragmentWear newInstance(String packageName) {
return setPackageName(new AppPermissionsFragmentWear(), packageName);
}
private static <T extends Fragment> T setPackageName(T fragment, String packageName) {
Bundle arguments = new Bundle();
arguments.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
fragment.setArguments(arguments);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String packageName = getArguments().getString(Intent.EXTRA_PACKAGE_NAME);
Activity activity = getActivity();
PackageManager pm = activity.getPackageManager();
PackageInfo packageInfo;
try {
packageInfo = pm.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS);
} catch (PackageManager.NameNotFoundException e) {
Log.i(LOG_TAG, "No package:" + activity.getCallingPackage(), e);
packageInfo = null;
}
if (packageInfo == null) {
Toast.makeText(activity, R.string.app_not_found_dlg_title, Toast.LENGTH_LONG).show();
activity.finish();
return;
}
mAppPermissions = new AppPermissions(activity, packageInfo, null, true, new Runnable() {
@Override
public void run() {
getActivity().finish();
}
});
mAdapter = new PermissionsSettingsAdapter(getContext());
initializePermissionGroupList();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.settings, container, false);
}
@Override
public void onResume() {
super.onResume();
mAppPermissions.refresh();
// Also refresh the UI
final int count = mAdapter.getItemCount();
for (int i = 0; i < count; ++i) {
updatePermissionGroupSetting(i);
}
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (mAppPermissions != null) {
initializeLayout(mAdapter);
mHeader.setText(R.string.app_permissions);
mDetails.setText(R.string.no_permissions);
if (mAdapter.getItemCount() == 0) {
mDetails.setVisibility(View.VISIBLE);
mWheel.setVisibility(View.GONE);
} else {
mDetails.setVisibility(View.GONE);
mWheel.setVisibility(View.VISIBLE);
}
}
}
private void initializePermissionGroupList() {
final String packageName = mAppPermissions.getPackageInfo().packageName;
List<AppPermissionGroup> groups = mAppPermissions.getPermissionGroups();
List<SettingsAdapter.Setting<AppPermissionGroup>> nonSystemGroups = new ArrayList<>();
final int count = groups.size();
for (int i = 0; i < count; ++i) {
final AppPermissionGroup group = groups.get(i);
if (!Utils.shouldShowPermission(group, packageName)) {
continue;
}
boolean isPlatform = group.getDeclaringPackage().equals(Utils.OS_PKG);
SettingsAdapter.Setting<AppPermissionGroup> setting =
new SettingsAdapter.Setting<AppPermissionGroup>(
group.getLabel(),
getPermissionGroupIcon(group),
i);
setting.data = group;
// The UI shows System settings first, then non-system settings
if (isPlatform) {
mAdapter.addSetting(setting);
} else {
nonSystemGroups.add(setting);
}
}
// Now add the non-system settings to the end of the list
final int nonSystemCount = nonSystemGroups.size();
for (int i = 0; i < nonSystemCount; ++i) {
final SettingsAdapter.Setting<AppPermissionGroup> setting = nonSystemGroups.get(i);
mAdapter.addSetting(setting);
}
}
@Override
public void onPause() {
super.onPause();
logAndClearToggledGroups();
}
@Override
public void onClick(WearableListView.ViewHolder view) {
final int index = view.getPosition();
SettingsAdapter.Setting<AppPermissionGroup> setting = mAdapter.get(index);
final AppPermissionGroup group = setting.data;
if (group == null) {
Log.e(LOG_TAG, "Error: AppPermissionGroup is null");
return;
}
// The way WearableListView is designed, there is no way to avoid this click handler
// Since the policy is fixed, ignore the click as the user is not able to change the state
// of this permission group
if (group.isPolicyFixed()) {
return;
}
addToggledGroup(group);
if (LocationUtils.isLocationGroupAndProvider(group.getName(), group.getApp().packageName)) {
LocationUtils.showLocationDialog(getContext(), mAppPermissions.getAppLabel());
return;
}
if (!group.areRuntimePermissionsGranted()) {
group.grantRuntimePermissions(false);
} else {
final boolean grantedByDefault = group.hasGrantedByDefaultPermission();
if (grantedByDefault || (!group.hasRuntimePermission() && !mHasConfirmedRevoke)) {
Intent intent = new Intent(getActivity(), WarningConfirmationActivity.class);
intent.putExtra(WarningConfirmationActivity.EXTRA_WARNING_MESSAGE,
getString(grantedByDefault ?
R.string.system_warning : R.string.old_sdk_deny_warning));
intent.putExtra(WarningConfirmationActivity.EXTRA_INDEX, index);
startActivityForResult(intent, WARNING_CONFIRMATION_REQUEST);
} else {
group.revokeRuntimePermissions(false);
}
}
updatePermissionGroupSetting(index);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == WARNING_CONFIRMATION_REQUEST) {
if (resultCode == Activity.RESULT_OK) {
int index = data.getIntExtra(WarningConfirmationActivity.EXTRA_INDEX, -1);
if (index == -1) {
Log.e(LOG_TAG, "Warning confirmation request came back with no index.");
return;
}
SettingsAdapter.Setting<AppPermissionGroup> setting = mAdapter.get(index);
final AppPermissionGroup group = setting.data;
group.revokeRuntimePermissions(false);
if (!group.hasGrantedByDefaultPermission()) {
mHasConfirmedRevoke = true;
}
updatePermissionGroupSetting(index);
}
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
private void updatePermissionGroupSetting(int index) {
SettingsAdapter.Setting<AppPermissionGroup> setting = mAdapter.get(index);
AppPermissionGroup group = setting.data;
mAdapter.updateSetting(
index,
group.getLabel(),
getPermissionGroupIcon(group),
group);
}
private void addToggledGroup(AppPermissionGroup group) {
if (mToggledGroups == null) {
mToggledGroups = new ArrayList<>();
}
// Double toggle is back to initial state.
if (mToggledGroups.contains(group)) {
mToggledGroups.remove(group);
} else {
mToggledGroups.add(group);
}
}
private void logAndClearToggledGroups() {
if (mToggledGroups != null) {
String packageName = mAppPermissions.getPackageInfo().packageName;
SafetyNetLogger.logPermissionsToggled(packageName, mToggledGroups);
mToggledGroups = null;
}
}
private int getPermissionGroupIcon(AppPermissionGroup group) {
String groupName = group.getName();
boolean isEnabled = group.areRuntimePermissionsGranted();
int resId;
switch (groupName) {
case Manifest.permission_group.CALENDAR:
resId = isEnabled ? R.drawable.ic_permission_calendar
: R.drawable.ic_permission_calendardisable;
break;
case Manifest.permission_group.CAMERA:
resId = isEnabled ? R.drawable.ic_permission_camera
: R.drawable.ic_permission_cameradisable;
break;
case Manifest.permission_group.CONTACTS:
resId = isEnabled ? R.drawable.ic_permission_contact
: R.drawable.ic_permission_contactdisable;
break;
case Manifest.permission_group.LOCATION:
resId = isEnabled ? R.drawable.ic_permission_location
: R.drawable.ic_permission_locationdisable;
break;
case Manifest.permission_group.MICROPHONE:
resId = isEnabled ? R.drawable.ic_permission_mic
: R.drawable.ic_permission_micdisable;
break;
case Manifest.permission_group.PHONE:
resId = isEnabled ? R.drawable.ic_permission_call
: R.drawable.ic_permission_calldisable;
break;
case Manifest.permission_group.SENSORS:
resId = isEnabled ? R.drawable.ic_permission_sensor
: R.drawable.ic_permission_sensordisable;
break;
case Manifest.permission_group.SMS:
resId = isEnabled ? R.drawable.ic_permission_sms
: R.drawable.ic_permission_smsdisable;
break;
case Manifest.permission_group.STORAGE:
resId = isEnabled ? R.drawable.ic_permission_storage
: R.drawable.ic_permission_storagedisable;
break;
default:
resId = isEnabled ? R.drawable.ic_permission_shield
: R.drawable.ic_permission_shielddisable;
}
return resId;
}
}