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 import com.android.systemui.res.R; 39 40 public class SlicePermissionActivity extends Activity implements OnClickListener, 41 OnDismissListener { 42 43 private static final String TAG = "SlicePermissionActivity"; 44 45 private CheckBox mAllCheckbox; 46 47 private Uri mUri; 48 private String mCallingPkg; 49 private String mProviderPkg; 50 51 @Override onCreate(Bundle savedInstanceState)52 protected void onCreate(Bundle savedInstanceState) { 53 super.onCreate(savedInstanceState); 54 55 // Verify intent is valid 56 try { 57 mUri = getIntent().getParcelableExtra(SliceProvider.EXTRA_BIND_URI); 58 } catch (Exception e) { 59 Log.w(TAG, "Failed to getParcelableExtra", e); 60 } 61 mCallingPkg = getIntent().getStringExtra(SliceProvider.EXTRA_PKG); 62 if (mUri == null 63 || !SliceProvider.SLICE_TYPE.equals(getContentResolver().getType(mUri)) 64 || !SliceManager.ACTION_REQUEST_SLICE_PERMISSION.equals(getIntent().getAction())) { 65 Log.e(TAG, "Intent is not valid"); 66 finish(); 67 return; 68 } 69 70 try { 71 PackageManager pm = getPackageManager(); 72 mProviderPkg = pm.resolveContentProvider(mUri.getAuthority(), 73 PackageManager.GET_META_DATA).applicationInfo.packageName; 74 verifyCallingPkg(); 75 CharSequence app1 = BidiFormatter.getInstance().unicodeWrap(pm.getApplicationInfo( 76 mCallingPkg, 0).loadSafeLabel(pm, PackageItemInfo.DEFAULT_MAX_LABEL_SIZE_PX, 77 PackageItemInfo.SAFE_LABEL_FLAG_TRIM 78 | PackageItemInfo.SAFE_LABEL_FLAG_FIRST_LINE).toString()); 79 CharSequence app2 = BidiFormatter.getInstance().unicodeWrap(pm.getApplicationInfo( 80 mProviderPkg, 0).loadSafeLabel(pm, PackageItemInfo.DEFAULT_MAX_LABEL_SIZE_PX, 81 PackageItemInfo.SAFE_LABEL_FLAG_TRIM 82 | PackageItemInfo.SAFE_LABEL_FLAG_FIRST_LINE).toString()); 83 AlertDialog dialog = new AlertDialog.Builder(this) 84 .setTitle(getString(R.string.slice_permission_title, app1, app2)) 85 .setView(R.layout.slice_permission_request) 86 .setNegativeButton(R.string.slice_permission_deny, this) 87 .setPositiveButton(R.string.slice_permission_allow, this) 88 .setOnDismissListener(this) 89 .create(); 90 dialog.getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); 91 dialog.show(); 92 TextView t1 = dialog.getWindow().getDecorView().findViewById(R.id.text1); 93 t1.setText(getString(R.string.slice_permission_text_1, app2)); 94 TextView t2 = dialog.getWindow().getDecorView().findViewById(R.id.text2); 95 t2.setText(getString(R.string.slice_permission_text_2, app2)); 96 mAllCheckbox = dialog.getWindow().getDecorView().findViewById( 97 R.id.slice_permission_checkbox); 98 mAllCheckbox.setText(getString(R.string.slice_permission_checkbox, app1)); 99 } catch (NameNotFoundException e) { 100 Log.e(TAG, "Couldn't find package", e); 101 finish(); 102 } 103 } 104 105 @Override onClick(DialogInterface dialog, int which)106 public void onClick(DialogInterface dialog, int which) { 107 if (which == DialogInterface.BUTTON_POSITIVE) { 108 getSystemService(SliceManager.class).grantPermissionFromUser(mUri, mCallingPkg, 109 mAllCheckbox.isChecked()); 110 } 111 finish(); 112 } 113 114 @Override onDismiss(DialogInterface dialog)115 public void onDismiss(DialogInterface dialog) { 116 finish(); 117 } 118 verifyCallingPkg()119 private void verifyCallingPkg() { 120 final String providerPkg = getIntent().getStringExtra("provider_pkg"); 121 if (providerPkg == null || mProviderPkg.equals(providerPkg)) return; 122 final String callingPkg = getCallingPkg(); 123 EventLog.writeEvent(0x534e4554, "159145361", getUid(callingPkg)); 124 } 125 126 @Nullable getCallingPkg()127 private String getCallingPkg() { 128 final Uri referrer = getReferrer(); 129 if (referrer == null) return null; 130 return referrer.getHost(); 131 } 132 getUid(@ullable final String pkg)133 private int getUid(@Nullable final String pkg) { 134 if (pkg == null) return -1; 135 try { 136 return getPackageManager().getApplicationInfo(pkg, 0).uid; 137 } catch (NameNotFoundException e) { 138 } 139 return -1; 140 } 141 } 142