1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 5 * except in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the 10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 11 * KIND, either express or implied. See the License for the specific language governing 12 * permissions and limitations under the License. 13 */ 14 15 package com.android.systemui; 16 17 import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS; 18 19 import android.annotation.Nullable; 20 import android.app.Activity; 21 import android.app.AlertDialog; 22 import android.app.slice.SliceManager; 23 import android.app.slice.SliceProvider; 24 import android.content.DialogInterface; 25 import android.content.DialogInterface.OnClickListener; 26 import android.content.DialogInterface.OnDismissListener; 27 import android.content.pm.PackageItemInfo; 28 import android.content.pm.PackageManager; 29 import android.content.pm.PackageManager.NameNotFoundException; 30 import android.net.Uri; 31 import android.os.Bundle; 32 import android.text.BidiFormatter; 33 import android.util.EventLog; 34 import android.util.Log; 35 import android.widget.CheckBox; 36 import android.widget.TextView; 37 38 public class SlicePermissionActivity extends Activity implements OnClickListener, 39 OnDismissListener { 40 41 private static final String TAG = "SlicePermissionActivity"; 42 43 private CheckBox mAllCheckbox; 44 45 private Uri mUri; 46 private String mCallingPkg; 47 private String mProviderPkg; 48 49 @Override onCreate(Bundle savedInstanceState)50 protected void onCreate(Bundle savedInstanceState) { 51 super.onCreate(savedInstanceState); 52 53 // Verify intent is valid 54 mUri = getIntent().getParcelableExtra(SliceProvider.EXTRA_BIND_URI); 55 mCallingPkg = getIntent().getStringExtra(SliceProvider.EXTRA_PKG); 56 if (mUri == null 57 || !SliceProvider.SLICE_TYPE.equals(getContentResolver().getType(mUri)) 58 || !SliceManager.ACTION_REQUEST_SLICE_PERMISSION.equals(getIntent().getAction())) { 59 Log.e(TAG, "Intent is not valid"); 60 finish(); 61 return; 62 } 63 64 try { 65 PackageManager pm = getPackageManager(); 66 mProviderPkg = pm.resolveContentProvider(mUri.getAuthority(), 67 PackageManager.GET_META_DATA).applicationInfo.packageName; 68 verifyCallingPkg(); 69 CharSequence app1 = BidiFormatter.getInstance().unicodeWrap(pm.getApplicationInfo( 70 mCallingPkg, 0).loadSafeLabel(pm, PackageItemInfo.DEFAULT_MAX_LABEL_SIZE_PX, 71 PackageItemInfo.SAFE_LABEL_FLAG_TRIM 72 | PackageItemInfo.SAFE_LABEL_FLAG_FIRST_LINE).toString()); 73 CharSequence app2 = BidiFormatter.getInstance().unicodeWrap(pm.getApplicationInfo( 74 mProviderPkg, 0).loadSafeLabel(pm, PackageItemInfo.DEFAULT_MAX_LABEL_SIZE_PX, 75 PackageItemInfo.SAFE_LABEL_FLAG_TRIM 76 | PackageItemInfo.SAFE_LABEL_FLAG_FIRST_LINE).toString()); 77 AlertDialog dialog = new AlertDialog.Builder(this) 78 .setTitle(getString(R.string.slice_permission_title, app1, app2)) 79 .setView(R.layout.slice_permission_request) 80 .setNegativeButton(R.string.slice_permission_deny, this) 81 .setPositiveButton(R.string.slice_permission_allow, this) 82 .setOnDismissListener(this) 83 .create(); 84 dialog.getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); 85 dialog.show(); 86 TextView t1 = dialog.getWindow().getDecorView().findViewById(R.id.text1); 87 t1.setText(getString(R.string.slice_permission_text_1, app2)); 88 TextView t2 = dialog.getWindow().getDecorView().findViewById(R.id.text2); 89 t2.setText(getString(R.string.slice_permission_text_2, app2)); 90 mAllCheckbox = dialog.getWindow().getDecorView().findViewById( 91 R.id.slice_permission_checkbox); 92 mAllCheckbox.setText(getString(R.string.slice_permission_checkbox, app1)); 93 } catch (NameNotFoundException e) { 94 Log.e(TAG, "Couldn't find package", e); 95 finish(); 96 } 97 } 98 99 @Override onClick(DialogInterface dialog, int which)100 public void onClick(DialogInterface dialog, int which) { 101 if (which == DialogInterface.BUTTON_POSITIVE) { 102 getSystemService(SliceManager.class).grantPermissionFromUser(mUri, mCallingPkg, 103 mAllCheckbox.isChecked()); 104 } 105 finish(); 106 } 107 108 @Override onDismiss(DialogInterface dialog)109 public void onDismiss(DialogInterface dialog) { 110 finish(); 111 } 112 verifyCallingPkg()113 private void verifyCallingPkg() { 114 final String providerPkg = getIntent().getStringExtra("provider_pkg"); 115 if (providerPkg == null || mProviderPkg.equals(providerPkg)) return; 116 final String callingPkg = getCallingPkg(); 117 EventLog.writeEvent(0x534e4554, "159145361", getUid(callingPkg)); 118 } 119 120 @Nullable getCallingPkg()121 private String getCallingPkg() { 122 final Uri referrer = getReferrer(); 123 if (referrer == null) return null; 124 return referrer.getHost(); 125 } 126 getUid(@ullable final String pkg)127 private int getUid(@Nullable final String pkg) { 128 if (pkg == null) return -1; 129 try { 130 return getPackageManager().getApplicationInfo(pkg, 0).uid; 131 } catch (NameNotFoundException e) { 132 } 133 return -1; 134 } 135 } 136