Merge "Add a "Do not ask again" checkbox." into nyc-dev
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
<?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.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingEnd="24dp"
|
||||
android:paddingStart="24dp" >
|
||||
|
||||
<TextView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/message"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingEnd="24dp"
|
||||
android:paddingStart="24dp"
|
||||
android:paddingTop="24dp"
|
||||
android:textAppearance="@android:style/TextAppearance.Material.Subhead"
|
||||
android:textColor="@*android:color/primary_text_default_material_light" >
|
||||
</TextView>
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/do_not_ask_checkbox"
|
||||
style="?android:attr/textAppearanceSmall"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dip"
|
||||
android:text="@string/never_ask_again"
|
||||
android:visibility="gone" />
|
||||
</LinearLayout>
|
||||
@@ -200,10 +200,12 @@
|
||||
during a copy. [CHAR LIMIT=48] -->
|
||||
<string name="notification_copy_files_converted_title">Some files were converted</string>
|
||||
|
||||
<!-- DO NOT TRANSLATE - final phrase has not been decided yet (b/26750152) -->
|
||||
<!-- Text in an alert dialog asking user to grant app access to a given directory in an external storage volume -->
|
||||
<string name="open_external_dialog_request">Grant <xliff:g id="appName" example="System Settings"><b>^1</b></xliff:g>
|
||||
access to <xliff:g id="directory" example="Pictures"><i>^2</i></xliff:g> folder on
|
||||
access to <xliff:g id="directory" example="Pictures"><i>^2</i></xliff:g> directory on
|
||||
<xliff:g id="storage" example="SD Card"><i>^3</i></xliff:g>?</string>
|
||||
<!-- Checkbox that allows user to not be questioned about the directory access request again -->
|
||||
<string name="never_ask_again">Don\'t ask again</string>
|
||||
<!-- Text in the button asking user to allow access to a given directory. -->
|
||||
<string name="allow">Allow</string>
|
||||
<!-- Text in the button asking user to deny access to a given directory. -->
|
||||
|
||||
@@ -16,10 +16,20 @@
|
||||
|
||||
package com.android.documentsui;
|
||||
|
||||
import static com.android.documentsui.Shared.DEBUG;
|
||||
import static com.android.documentsui.Shared.TAG;
|
||||
import static com.android.documentsui.State.MODE_UNKNOWN;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.UserHandle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.documentsui.State.ViewMode;
|
||||
import com.android.documentsui.model.RootInfo;
|
||||
@@ -29,29 +39,73 @@ public class LocalPreferences {
|
||||
private static final String ROOT_VIEW_MODE_PREFIX = "rootViewMode-";
|
||||
|
||||
public static boolean getDisplayFileSize(Context context) {
|
||||
return PreferenceManager.getDefaultSharedPreferences(context)
|
||||
.getBoolean(KEY_FILE_SIZE, false);
|
||||
return getPrefs(context).getBoolean(KEY_FILE_SIZE, false);
|
||||
}
|
||||
|
||||
public static @ViewMode int getViewMode(
|
||||
Context context, RootInfo root, @ViewMode int fallback) {
|
||||
return PreferenceManager.getDefaultSharedPreferences(context)
|
||||
.getInt(createKey(root), fallback);
|
||||
public static @ViewMode int getViewMode(Context context, RootInfo root,
|
||||
@ViewMode int fallback) {
|
||||
return getPrefs(context).getInt(createKey(root), fallback);
|
||||
}
|
||||
|
||||
public static void setDisplayFileSize(Context context, boolean display) {
|
||||
PreferenceManager.getDefaultSharedPreferences(context).edit()
|
||||
.putBoolean(KEY_FILE_SIZE, display).apply();
|
||||
getPrefs(context).edit().putBoolean(KEY_FILE_SIZE, display).apply();
|
||||
}
|
||||
|
||||
public static void setViewMode(Context context, RootInfo root, @ViewMode int viewMode) {
|
||||
assert(viewMode != MODE_UNKNOWN);
|
||||
|
||||
PreferenceManager.getDefaultSharedPreferences(context).edit()
|
||||
.putInt(createKey(root), viewMode).apply();
|
||||
getPrefs(context).edit().putInt(createKey(root), viewMode).apply();
|
||||
}
|
||||
|
||||
private static SharedPreferences getPrefs(Context context) {
|
||||
return PreferenceManager.getDefaultSharedPreferences(context);
|
||||
}
|
||||
|
||||
private static String createKey(RootInfo root) {
|
||||
return ROOT_VIEW_MODE_PREFIX + root.authority + root.rootId;
|
||||
}
|
||||
|
||||
public static final int PERMISSION_ASK = 0;
|
||||
public static final int PERMISSION_ASK_AGAIN = 1;
|
||||
public static final int PERMISSION_NEVER_ASK = -1;
|
||||
|
||||
@IntDef(flag = true, value = {
|
||||
PERMISSION_ASK,
|
||||
PERMISSION_ASK_AGAIN,
|
||||
PERMISSION_NEVER_ASK,
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface PermissionStatus {}
|
||||
|
||||
/**
|
||||
* Methods below are used to keep track of denied user requests on scoped directory access so
|
||||
* the dialog is not offered when user checked the 'Do not ask again' box
|
||||
*
|
||||
* <p>It uses a shared preferences, whose key is:
|
||||
* <ol>
|
||||
* <li>{@code USER_ID|PACKAGE_NAME|VOLUME_UUID|DIRECTORY} for storage volumes that have a UUID
|
||||
* (typically physical volumes like SD cards).
|
||||
* <li>{@code USER_ID|PACKAGE_NAME||DIRECTORY} for storage volumes that do not have a UUID
|
||||
* (typically the emulated volume used for primary storage
|
||||
* </ol>
|
||||
*/
|
||||
static @PermissionStatus int getScopedAccessPermissionStatus(Context context,
|
||||
String packageName, @Nullable String uuid, String directory) {
|
||||
final String key = getScopedAccessDenialsKey(packageName, uuid, directory);
|
||||
return getPrefs(context).getInt(key, PERMISSION_ASK);
|
||||
}
|
||||
|
||||
static void setScopedAccessPermissionStatus(Context context, String packageName,
|
||||
@Nullable String uuid, String directory, @PermissionStatus int status) {
|
||||
final String key = getScopedAccessDenialsKey(packageName, uuid, directory);
|
||||
getPrefs(context).edit().putInt(key, status).apply();
|
||||
}
|
||||
|
||||
private static String getScopedAccessDenialsKey(String packageName, String uuid,
|
||||
String directory) {
|
||||
final int userId = UserHandle.myUserId();
|
||||
return uuid == null
|
||||
? userId + "|" + packageName + "||" + directory
|
||||
: userId + "|" + packageName + "|" + uuid + "|" + directory;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -411,11 +411,15 @@ public final class Metrics {
|
||||
public static final int SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED = 0;
|
||||
public static final int SCOPED_DIRECTORY_ACCESS_GRANTED = 1;
|
||||
public static final int SCOPED_DIRECTORY_ACCESS_DENIED = 2;
|
||||
public static final int SCOPED_DIRECTORY_ACCESS_DENIED_AND_PERSIST = 3;
|
||||
public static final int SCOPED_DIRECTORY_ACCESS_ALREADY_DENIED = 4;
|
||||
|
||||
@IntDef(flag = true, value = {
|
||||
SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED,
|
||||
SCOPED_DIRECTORY_ACCESS_GRANTED,
|
||||
SCOPED_DIRECTORY_ACCESS_DENIED
|
||||
SCOPED_DIRECTORY_ACCESS_DENIED,
|
||||
SCOPED_DIRECTORY_ACCESS_DENIED_AND_PERSIST,
|
||||
SCOPED_DIRECTORY_ACCESS_ALREADY_DENIED
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface ScopedAccessGrant {}
|
||||
@@ -432,23 +436,34 @@ public final class Metrics {
|
||||
final String packageName = activity.getCallingPackage();
|
||||
switch (type) {
|
||||
case SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED:
|
||||
MetricsLogger.action(activity,
|
||||
MetricsEvent.ACTION_SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED_BY_PACKAGE,
|
||||
packageName);
|
||||
MetricsLogger.action(activity,
|
||||
MetricsEvent.ACTION_SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED_BY_FOLDER, index);
|
||||
MetricsLogger.action(activity, MetricsEvent
|
||||
.ACTION_SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED_BY_PACKAGE, packageName);
|
||||
MetricsLogger.action(activity, MetricsEvent
|
||||
.ACTION_SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED_BY_FOLDER, index);
|
||||
break;
|
||||
case SCOPED_DIRECTORY_ACCESS_GRANTED:
|
||||
MetricsLogger.action(activity,
|
||||
MetricsEvent.ACTION_SCOPED_DIRECTORY_ACCESS_GRANTED_BY_PACKAGE, packageName);
|
||||
MetricsLogger.action(activity,
|
||||
MetricsEvent.ACTION_SCOPED_DIRECTORY_ACCESS_GRANTED_BY_FOLDER, index);
|
||||
MetricsLogger.action(activity, MetricsEvent
|
||||
.ACTION_SCOPED_DIRECTORY_ACCESS_GRANTED_BY_PACKAGE, packageName);
|
||||
MetricsLogger.action(activity, MetricsEvent
|
||||
.ACTION_SCOPED_DIRECTORY_ACCESS_GRANTED_BY_FOLDER, index);
|
||||
break;
|
||||
case SCOPED_DIRECTORY_ACCESS_DENIED:
|
||||
MetricsLogger.action(activity,
|
||||
MetricsEvent.ACTION_SCOPED_DIRECTORY_ACCESS_DENIED_BY_PACKAGE, packageName);
|
||||
MetricsLogger.action(activity,
|
||||
MetricsEvent.ACTION_SCOPED_DIRECTORY_ACCESS_DENIED_BY_FOLDER, index);
|
||||
MetricsLogger.action(activity, MetricsEvent
|
||||
.ACTION_SCOPED_DIRECTORY_ACCESS_DENIED_BY_PACKAGE, packageName);
|
||||
MetricsLogger.action(activity, MetricsEvent
|
||||
.ACTION_SCOPED_DIRECTORY_ACCESS_DENIED_BY_FOLDER, index);
|
||||
break;
|
||||
case SCOPED_DIRECTORY_ACCESS_DENIED_AND_PERSIST:
|
||||
MetricsLogger.action(activity, MetricsEvent
|
||||
.ACTION_SCOPED_DIRECTORY_ACCESS_DENIED_AND_PERSIST_BY_PACKAGE, packageName);
|
||||
MetricsLogger.action(activity, MetricsEvent
|
||||
.ACTION_SCOPED_DIRECTORY_ACCESS_DENIED_AND_PERSIST_BY_FOLDER, index);
|
||||
break;
|
||||
case SCOPED_DIRECTORY_ACCESS_ALREADY_DENIED:
|
||||
MetricsLogger.action(activity, MetricsEvent
|
||||
.ACTION_SCOPED_DIRECTORY_ACCESS_ALREADY_DENIED_BY_PACKAGE, packageName);
|
||||
MetricsLogger.action(activity, MetricsEvent
|
||||
.ACTION_SCOPED_DIRECTORY_ACCESS_ALREADY_DENIED_BY_FOLDER, index);
|
||||
break;
|
||||
default:
|
||||
Log.wtf(TAG, "invalid ScopedAccessGrant: " + type);
|
||||
|
||||
@@ -20,16 +20,24 @@ import static android.os.Environment.isStandardDirectory;
|
||||
import static android.os.Environment.STANDARD_DIRECTORIES;
|
||||
import static android.os.storage.StorageVolume.EXTRA_DIRECTORY_NAME;
|
||||
import static android.os.storage.StorageVolume.EXTRA_STORAGE_VOLUME;
|
||||
import static com.android.documentsui.Shared.DEBUG;
|
||||
import static com.android.documentsui.Metrics.logInvalidScopedAccessRequest;
|
||||
import static com.android.documentsui.Metrics.logValidScopedAccessRequest;
|
||||
import static com.android.documentsui.LocalPreferences.getScopedAccessPermissionStatus;
|
||||
import static com.android.documentsui.LocalPreferences.PERMISSION_ASK;
|
||||
import static com.android.documentsui.LocalPreferences.PERMISSION_ASK_AGAIN;
|
||||
import static com.android.documentsui.LocalPreferences.PERMISSION_NEVER_ASK;
|
||||
import static com.android.documentsui.LocalPreferences.setScopedAccessPermissionStatus;
|
||||
import static com.android.documentsui.Metrics.SCOPED_DIRECTORY_ACCESS_ALREADY_DENIED;
|
||||
import static com.android.documentsui.Metrics.SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED;
|
||||
import static com.android.documentsui.Metrics.SCOPED_DIRECTORY_ACCESS_DENIED;
|
||||
import static com.android.documentsui.Metrics.SCOPED_DIRECTORY_ACCESS_DENIED_AND_PERSIST;
|
||||
import static com.android.documentsui.Metrics.SCOPED_DIRECTORY_ACCESS_ERROR;
|
||||
import static com.android.documentsui.Metrics.SCOPED_DIRECTORY_ACCESS_GRANTED;
|
||||
import static com.android.documentsui.Metrics.SCOPED_DIRECTORY_ACCESS_INVALID_ARGUMENTS;
|
||||
import static com.android.documentsui.Metrics.SCOPED_DIRECTORY_ACCESS_INVALID_DIRECTORY;
|
||||
import static com.android.documentsui.Metrics.logInvalidScopedAccessRequest;
|
||||
import static com.android.documentsui.Metrics.logValidScopedAccessRequest;
|
||||
import static com.android.documentsui.Shared.DEBUG;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.AlertDialog;
|
||||
@@ -38,7 +46,6 @@ import android.app.DialogFragment;
|
||||
import android.app.FragmentManager;
|
||||
import android.app.FragmentTransaction;
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.DialogInterface.OnClickListener;
|
||||
@@ -57,6 +64,11 @@ import android.os.storage.VolumeInfo;
|
||||
import android.provider.DocumentsContract;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.CompoundButton.OnCheckedChangeListener;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -72,12 +84,17 @@ public class OpenExternalDirectoryActivity extends Activity {
|
||||
private static final String EXTRA_FILE = "com.android.documentsui.FILE";
|
||||
private static final String EXTRA_APP_LABEL = "com.android.documentsui.APP_LABEL";
|
||||
private static final String EXTRA_VOLUME_LABEL = "com.android.documentsui.VOLUME_LABEL";
|
||||
private static final String EXTRA_VOLUME_UUID = "com.android.documentsui.VOLUME_UUID";
|
||||
|
||||
private ContentProviderClient mExternalStorageClient;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if (savedInstanceState != null) {
|
||||
if (DEBUG) Log.d(TAG, "activity.onCreateDialog(): reusing instance");
|
||||
return;
|
||||
}
|
||||
|
||||
final Intent intent = getIntent();
|
||||
if (intent == null) {
|
||||
@@ -105,9 +122,18 @@ public class OpenExternalDirectoryActivity extends Activity {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
final StorageVolume volume = (StorageVolume) storageVolume;
|
||||
if (getScopedAccessPermissionStatus(getApplicationContext(), getCallingPackage(),
|
||||
volume.getUuid(), directoryName) == PERMISSION_NEVER_ASK) {
|
||||
logValidScopedAccessRequest(this, directoryName,
|
||||
SCOPED_DIRECTORY_ACCESS_ALREADY_DENIED);
|
||||
setResult(RESULT_CANCELED);
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
final int userId = UserHandle.myUserId();
|
||||
if (!showFragment(this, userId, (StorageVolume) storageVolume, directoryName)) {
|
||||
if (!showFragment(this, userId, volume, directoryName)) {
|
||||
setResult(RESULT_CANCELED);
|
||||
finish();
|
||||
return;
|
||||
@@ -157,6 +183,7 @@ public class OpenExternalDirectoryActivity extends Activity {
|
||||
|
||||
// Gets volume label and converted path.
|
||||
String volumeLabel = null;
|
||||
String volumeUuid = null;
|
||||
final List<VolumeInfo> volumes = sm.getVolumes();
|
||||
if (DEBUG) Log.d(TAG, "Number of volumes: " + volumes.size());
|
||||
for (VolumeInfo volume : volumes) {
|
||||
@@ -166,6 +193,7 @@ public class OpenExternalDirectoryActivity extends Activity {
|
||||
if (DEBUG) Log.d(TAG, "Converting " + root + " to " + internalRoot);
|
||||
file = new File(internalRoot, directory);
|
||||
volumeLabel = sm.getBestVolumeDescription(volume);
|
||||
volumeUuid = volume.getFsUuid();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -197,6 +225,7 @@ public class OpenExternalDirectoryActivity extends Activity {
|
||||
final Bundle args = new Bundle();
|
||||
args.putString(EXTRA_FILE, file.getAbsolutePath());
|
||||
args.putString(EXTRA_VOLUME_LABEL, volumeLabel);
|
||||
args.putString(EXTRA_VOLUME_UUID, volumeUuid);
|
||||
args.putString(EXTRA_APP_LABEL, appLabel);
|
||||
|
||||
final FragmentManager fm = activity.getFragmentManager();
|
||||
@@ -303,26 +332,50 @@ public class OpenExternalDirectoryActivity extends Activity {
|
||||
public static class OpenExternalDirectoryDialogFragment extends DialogFragment {
|
||||
|
||||
private File mFile;
|
||||
private String mVolumeUuid;
|
||||
private String mVolumeLabel;
|
||||
private String mAppLabel;
|
||||
private CheckBox mDontAskAgain;
|
||||
private OpenExternalDirectoryActivity mActivity;
|
||||
private AlertDialog mDialog;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setRetainInstance(true);
|
||||
final Bundle args = getArguments();
|
||||
if (args != null) {
|
||||
mFile = new File(args.getString(EXTRA_FILE));
|
||||
mVolumeUuid = args.getString(EXTRA_VOLUME_UUID);
|
||||
mVolumeLabel = args.getString(EXTRA_VOLUME_LABEL);
|
||||
mAppLabel = args.getString(EXTRA_APP_LABEL);
|
||||
}
|
||||
mActivity = (OpenExternalDirectoryActivity) getActivity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
// Workaround for https://code.google.com/p/android/issues/detail?id=17423
|
||||
if (mDialog != null && getRetainInstance()) {
|
||||
mDialog.setDismissMessage(null);
|
||||
}
|
||||
super.onDestroyView();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
if (mDialog != null) {
|
||||
if (DEBUG) Log.d(TAG, "fragment.onCreateDialog(): reusing dialog");
|
||||
return mDialog;
|
||||
}
|
||||
if (mActivity != getActivity()) {
|
||||
// Sanity check.
|
||||
Log.wtf(TAG, "activity references don't match on onCreateDialog(): mActivity = "
|
||||
+ mActivity + " , getActivity() = " + getActivity());
|
||||
mActivity = (OpenExternalDirectoryActivity) getActivity();
|
||||
}
|
||||
final String directory = mFile.getName();
|
||||
final Activity activity = getActivity();
|
||||
final Context context = mActivity.getApplicationContext();
|
||||
final OnClickListener listener = new OnClickListener() {
|
||||
|
||||
@Override
|
||||
@@ -333,15 +386,25 @@ public class OpenExternalDirectoryActivity extends Activity {
|
||||
mActivity.getExternalStorageClient(), mFile);
|
||||
}
|
||||
if (which == DialogInterface.BUTTON_NEGATIVE || intent == null) {
|
||||
logValidScopedAccessRequest(activity, directory,
|
||||
logValidScopedAccessRequest(mActivity, directory,
|
||||
SCOPED_DIRECTORY_ACCESS_DENIED);
|
||||
activity.setResult(RESULT_CANCELED);
|
||||
final boolean checked = mDontAskAgain.isChecked();
|
||||
if (checked) {
|
||||
logValidScopedAccessRequest(mActivity, directory,
|
||||
SCOPED_DIRECTORY_ACCESS_DENIED_AND_PERSIST);
|
||||
setScopedAccessPermissionStatus(context, mActivity.getCallingPackage(),
|
||||
mVolumeUuid, directory, PERMISSION_NEVER_ASK);
|
||||
} else {
|
||||
setScopedAccessPermissionStatus(context, mActivity.getCallingPackage(),
|
||||
mVolumeUuid, directory, PERMISSION_ASK_AGAIN);
|
||||
}
|
||||
mActivity.setResult(RESULT_CANCELED);
|
||||
} else {
|
||||
logValidScopedAccessRequest(activity, directory,
|
||||
logValidScopedAccessRequest(mActivity, directory,
|
||||
SCOPED_DIRECTORY_ACCESS_GRANTED);
|
||||
activity.setResult(RESULT_OK, intent);
|
||||
mActivity.setResult(RESULT_OK, intent);
|
||||
}
|
||||
activity.finish();
|
||||
mActivity.finish();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -349,11 +412,31 @@ public class OpenExternalDirectoryActivity extends Activity {
|
||||
.expandTemplate(
|
||||
getText(R.string.open_external_dialog_request), mAppLabel, directory,
|
||||
mVolumeLabel);
|
||||
return new AlertDialog.Builder(activity, R.style.AlertDialogTheme)
|
||||
.setMessage(message)
|
||||
@SuppressLint("InflateParams")
|
||||
// It's ok pass null ViewRoot on AlertDialogs.
|
||||
final View view = View.inflate(mActivity, R.layout.dialog_open_scoped_directory, null);
|
||||
final TextView messageField = (TextView) view.findViewById(R.id.message);
|
||||
messageField.setText(message);
|
||||
mDialog = new AlertDialog.Builder(mActivity, R.style.AlertDialogTheme)
|
||||
.setView(view)
|
||||
.setPositiveButton(R.string.allow, listener)
|
||||
.setNegativeButton(R.string.deny, listener)
|
||||
.create();
|
||||
|
||||
mDontAskAgain = (CheckBox) view.findViewById(R.id.do_not_ask_checkbox);
|
||||
if (getScopedAccessPermissionStatus(context, mActivity.getCallingPackage(),
|
||||
mVolumeUuid, directory) == PERMISSION_ASK_AGAIN) {
|
||||
mDontAskAgain.setVisibility(View.VISIBLE);
|
||||
mDontAskAgain.setOnCheckedChangeListener(new OnCheckedChangeListener() {
|
||||
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
mDialog.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(!isChecked);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return mDialog;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1996,6 +1996,22 @@ message MetricsEvent {
|
||||
// Logs that the user docks window via shortcut key.
|
||||
WINDOW_DOCK_SHORTCUTS = 352;
|
||||
|
||||
// User already denied access to the request folder; action takes an integer
|
||||
// representing the folder's index on Environment.STANDARD_DIRECTORIES
|
||||
ACTION_SCOPED_DIRECTORY_ACCESS_ALREADY_DENIED_BY_FOLDER = 353;
|
||||
|
||||
// User already denied access to the request folder; action pass package name
|
||||
// of calling package.
|
||||
ACTION_SCOPED_DIRECTORY_ACCESS_ALREADY_DENIED_BY_PACKAGE = 354;
|
||||
|
||||
// User denied access to the request folder and checked 'Do not ask again';
|
||||
// action takes an integer representing the folder's index on Environment.STANDARD_DIRECTORIES
|
||||
ACTION_SCOPED_DIRECTORY_ACCESS_DENIED_AND_PERSIST_BY_FOLDER = 355;
|
||||
|
||||
// User denied access to the request folder and checked 'Do not ask again';
|
||||
// action pass package name of calling package.
|
||||
ACTION_SCOPED_DIRECTORY_ACCESS_DENIED_AND_PERSIST_BY_PACKAGE = 356;
|
||||
|
||||
// Add new aosp constants above this line.
|
||||
// END OF AOSP CONSTANTS
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user