Added option do display and clear URI permissions.

BUG: 26447975
Change-Id: If5269a62908ce37501219ca8dba619041812d800
This commit is contained in:
Felipe Leme
2016-01-08 09:53:29 -08:00
parent 22b9e6dcdf
commit 08703c8bb1
4 changed files with 149 additions and 2 deletions

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2016 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.
-->
<!-- Style for a preference category without a header title.
Based on tall_preference_category, but invisible and with some 0dp attributes. -->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+android:id/title"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="0dip"
android:textAppearance="@android:style/TextAppearance.Material.Body2"
android:textColor="?android:attr/colorAccent"
android:paddingBottom="8dp"
android:paddingTop="16dip"
android:visible="false" />

View File

@@ -3065,6 +3065,13 @@
<string name="clear_cache_btn_text">Clear cache</string>
<!-- Manage applications, label that appears next to the cache size -->
<string name="cache_size_label">Cache</string>
<!-- Manage applications, individual application info storage screen. Describes the number of URIs (directories or files) an app has been granted access (by another apps)-->
<plurals name="uri_permissions_text">
<item quantity="one">1 item</item>
<item quantity="other">%d items</item>
</plurals>
<!-- Manage applications, individual application info storage screen. Button below list of URIs. -->
<string name="clear_uri_btn_text">Clear access</string>
<!-- Manage applications, Header name used for other controls -->
<string name="controls_label">Controls</string>
<!-- Manage applications, text label for button to kill / force stop an application -->

View File

@@ -86,4 +86,16 @@
android:selectable="false"
android:layout="@layout/single_button_panel" />
<com.android.settings.applications.SpacePreference
android:layout_height="8dp" />
<PreferenceCategory
android:key="uri_category"
android:layout="@layout/headerless_preference_category" >
<com.android.settings.applications.LayoutPreference
android:key="clear_uri_button"
android:layout="@layout/single_button_panel"
android:selectable="false" />
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -22,9 +22,11 @@ import android.app.AppGlobals;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.UriPermission;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageDataObserver;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
@@ -37,6 +39,7 @@ import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceCategory;
import android.text.format.Formatter;
import android.util.Log;
import android.util.MutableInt;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
@@ -49,9 +52,12 @@ import com.android.settingslib.applications.ApplicationsState;
import com.android.settingslib.applications.ApplicationsState.AppEntry;
import com.android.settingslib.applications.ApplicationsState.Callbacks;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.TreeMap;
public class AppStorageSettings extends AppInfoWithHeader
implements OnClickListener, Callbacks, DialogInterface.OnClickListener {
@@ -88,6 +94,9 @@ public class AppStorageSettings extends AppInfoWithHeader
private static final String KEY_CLEAR_DATA = "clear_data_button";
private static final String KEY_CLEAR_CACHE = "clear_cache_button";
private static final String KEY_URI_CATEGORY = "uri_category";
private static final String KEY_CLEAR_URI = "clear_uri_button";
private Preference mTotalSize;
private Preference mAppSize;
private Preference mDataSize;
@@ -102,6 +111,11 @@ public class AppStorageSettings extends AppInfoWithHeader
private Preference mStorageUsed;
private Button mChangeStorageButton;
// Views related to URI permissions
private Button mClearUriButton;
private LayoutPreference mClearUri;
private PreferenceCategory mUri;
private boolean mCanClearData = true;
private boolean mHaveSizes = false;
@@ -166,6 +180,13 @@ public class AppStorageSettings extends AppInfoWithHeader
mClearCacheButton = (Button) ((LayoutPreference) findPreference(KEY_CLEAR_CACHE))
.findViewById(R.id.button);
mClearCacheButton.setText(R.string.clear_cache_btn_text);
// URI permissions section
mUri = (PreferenceCategory) findPreference(KEY_URI_CATEGORY);
mClearUri = (LayoutPreference) mUri.findPreference(KEY_CLEAR_URI);
mClearUriButton = (Button) mClearUri.findViewById(R.id.button);
mClearUriButton.setText(R.string.clear_uri_btn_text);
mClearUriButton.setOnClickListener(this);
}
@Override
@@ -189,6 +210,8 @@ public class AppStorageSettings extends AppInfoWithHeader
}
} else if (v == mChangeStorageButton && mDialogBuilder != null && !isMoveInProgress()) {
mDialogBuilder.show();
} else if (v == mClearUriButton) {
clearUriPermissions();
}
}
@@ -239,7 +262,6 @@ public class AppStorageSettings extends AppInfoWithHeader
}
mClearDataButton.setEnabled(false);
mClearCacheButton.setEnabled(false);
} else {
mHaveSizes = true;
long codeSize = mAppEntry.codeSize;
@@ -301,6 +323,7 @@ public class AppStorageSettings extends AppInfoWithHeader
return false;
}
refreshSizeInfo();
refreshGrantedUriPermissions();
final VolumeInfo currentVol = getActivity().getPackageManager()
.getPackageCurrentVolume(mAppEntry.info);
@@ -413,6 +436,83 @@ public class AppStorageSettings extends AppInfoWithHeader
}
}
private void refreshGrantedUriPermissions() {
// Clear UI first (in case the activity has been resumed)
removeUriPermissionsFromUi();
// Gets all URI permissions from am.
ActivityManager am = (ActivityManager) getActivity().getSystemService(
Context.ACTIVITY_SERVICE);
List<UriPermission> perms =
am.getGrantedUriPermissions(mAppEntry.info.packageName).getList();
if (perms.isEmpty()) {
mClearUriButton.setVisibility(View.GONE);
return;
}
PackageManager pm = getActivity().getPackageManager();
// Group number of URIs by app.
Map<CharSequence, MutableInt> uriCounters = new TreeMap<>();
for (UriPermission perm : perms) {
String authority = perm.getUri().getAuthority();
ProviderInfo provider = pm.resolveContentProvider(authority, 0);
CharSequence app = provider.applicationInfo.loadLabel(pm);
MutableInt count = uriCounters.get(app);
if (count == null) {
uriCounters.put(app, new MutableInt(1));
} else {
count.value++;
}
}
// Dynamically add the preferences, one per app.
int order = 0;
for (Map.Entry<CharSequence, MutableInt> entry : uriCounters.entrySet()) {
int numberResources = entry.getValue().value;
Preference pref = new Preference(getPrefContext());
pref.setTitle(entry.getKey());
pref.setSummary(getPrefContext().getResources()
.getQuantityString(R.plurals.uri_permissions_text, numberResources,
numberResources));
pref.setSelectable(false);
pref.setLayoutResource(R.layout.horizontal_preference);
pref.setOrder(order);
Log.v(TAG, "Adding preference '" + pref + "' at order " + order);
mUri.addPreference(pref);
}
if (mAppControlRestricted) {
mClearUriButton.setEnabled(false);
}
mClearUri.setOrder(order);
mClearUriButton.setVisibility(View.VISIBLE);
}
private void clearUriPermissions() {
// Synchronously revoke the permissions.
final ActivityManager am = (ActivityManager) getActivity().getSystemService(
Context.ACTIVITY_SERVICE);
am.clearGrantedUriPermissions(mAppEntry.info.packageName);
// Update UI
refreshGrantedUriPermissions();
}
private void removeUriPermissionsFromUi() {
// Remove all preferences but the clear button.
int count = mUri.getPreferenceCount();
for (int i = count - 1; i >= 0; i--) {
Preference pref = mUri.getPreference(i);
if (pref != mClearUri) {
mUri.removePreference(pref);
}
}
}
@Override
protected AlertDialog createDialog(int id, int errorCode) {
switch (id) {