Added option do display and clear URI permissions.
BUG: 26447975 Change-Id: If5269a62908ce37501219ca8dba619041812d800
This commit is contained in:
28
res/layout/headerless_preference_category.xml
Normal file
28
res/layout/headerless_preference_category.xml
Normal 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" />
|
@@ -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 -->
|
||||
|
@@ -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>
|
||||
|
@@ -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) {
|
||||
|
Reference in New Issue
Block a user