blob: 8498a1808296b741002f420b2a53068d04edbbe2 [file] [log] [blame]
/*
* Copyright (C) 2018 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.providers.media;
import static com.android.providers.media.MediaProvider.TAG;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.MediaStore.MediaColumns;
import android.text.TextUtils;
import android.util.Log;
import android.util.Size;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.TextView;
import com.android.internal.app.AlertActivity;
import java.io.IOException;
public class PermissionActivity extends AlertActivity implements DialogInterface.OnClickListener {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final CharSequence label;
final int resId;
try {
label = getCallingLabel();
resId = getMessageId();
} catch (Exception e) {
Log.w(TAG, e);
finish();
return;
}
final Resources res = getResources();
final FrameLayout view = new FrameLayout(this);
final int padding = res.getDimensionPixelSize(com.android.internal.R.dimen.default_gap);
view.setPadding(padding, padding, padding, padding);
new AsyncTask<Void, Void, Description>() {
@Override
protected Description doInBackground(Void... params) {
try {
return new Description(PermissionActivity.this, getIntent().getData());
} catch (Exception e) {
Log.w(TAG, e);
finish();
return null;
}
}
@Override
protected void onPostExecute(Description result) {
if (result == null) return;
if (result.thumbnail != null) {
Log.d(TAG, "Found thumbnail " + result.thumbnail.getWidth() + "x"
+ result.thumbnail.getHeight());
final ImageView child = new ImageView(PermissionActivity.this);
child.setScaleType(ScaleType.CENTER_INSIDE);
child.setImageBitmap(result.thumbnail);
child.setContentDescription(result.contentDescription);
view.addView(child);
} else {
Log.d(TAG, "Found description " + result.contentDescription);
final TextView child = new TextView(PermissionActivity.this);
child.setText(result.contentDescription);
view.addView(child);
}
}
}.execute();
mAlertParams.mMessage = TextUtils.expandTemplate(getText(resId), label);
mAlertParams.mPositiveButtonText = getString(R.string.grant_dialog_button_allow);
mAlertParams.mPositiveButtonListener = this;
mAlertParams.mNegativeButtonText = getString(R.string.grant_dialog_button_deny);
mAlertParams.mNegativeButtonListener = this;
mAlertParams.mCancelable = false;
mAlertParams.mView = view;
setupAlert();
getWindow().setCloseOnTouchOutside(false);
getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
}
@Override
public void onClick(DialogInterface dialog, int which) {
final Uri uri = getIntent().getData();
switch (which) {
case BUTTON_POSITIVE:
Log.d(TAG, "User allowed grant for " + uri);
grantUriPermission(getCallingPackage(), uri,
Intent.FLAG_GRANT_READ_URI_PERMISSION |
Intent.FLAG_GRANT_WRITE_URI_PERMISSION |
Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
setResult(Activity.RESULT_OK);
finish();
break;
case BUTTON_NEGATIVE:
Log.d(TAG, "User declined grant for " + uri);
finish();
break;
}
}
private CharSequence getCallingLabel() throws NameNotFoundException {
final String callingPackage = getCallingPackage();
if (TextUtils.isEmpty(callingPackage)) {
throw new NameNotFoundException("Missing calling package");
}
final PackageManager pm = getPackageManager();
final CharSequence callingLabel = pm
.getApplicationLabel(pm.getApplicationInfo(callingPackage, 0));
if (TextUtils.isEmpty(callingLabel)) {
throw new NameNotFoundException("Missing calling package");
}
return callingLabel;
}
private int getMessageId() throws NameNotFoundException {
final Uri uri = getIntent().getData();
final String type = uri.getPathSegments().get(1);
switch (type) {
case "audio": return R.string.permission_audio;
case "video": return R.string.permission_video;
case "images": return R.string.permission_images;
}
throw new NameNotFoundException("Unknown media type " + uri);
}
private static class Description {
public Bitmap thumbnail;
public CharSequence contentDescription;
public Description(Context context, Uri uri) {
final Resources res = context.getResources();
final ContentResolver resolver = context.getContentResolver();
final Size size = new Size(res.getDisplayMetrics().widthPixels,
res.getDisplayMetrics().widthPixels);
try {
thumbnail = resolver.loadThumbnail(uri, size, null);
} catch (IOException e) {
Log.w(TAG, e);
}
try (Cursor c = resolver.query(uri,
new String[] { MediaColumns.DISPLAY_NAME }, null, null)) {
if (c.moveToFirst()) {
contentDescription = c.getString(0);
}
}
if (TextUtils.isEmpty(contentDescription)) {
throw new IllegalStateException();
}
}
}
}