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         mUri = getIntent().getParcelableExtra(SliceProvider.EXTRA_BIND_URI);
54         mCallingPkg = getIntent().getStringExtra(SliceProvider.EXTRA_PKG);
55         if (mUri == null) {
56             Log.e(TAG, SliceProvider.EXTRA_BIND_URI + " wasn't provided");
57             finish();
58             return;
59         }
60 
61         try {
62             PackageManager pm = getPackageManager();
63             mProviderPkg = pm.resolveContentProvider(mUri.getAuthority(),
64                     PackageManager.GET_META_DATA).applicationInfo.packageName;
65             verifyCallingPkg();
66             CharSequence app1 = BidiFormatter.getInstance().unicodeWrap(pm.getApplicationInfo(
67                     mCallingPkg, 0).loadSafeLabel(pm, PackageItemInfo.DEFAULT_MAX_LABEL_SIZE_PX,
68                     PackageItemInfo.SAFE_LABEL_FLAG_TRIM
69                             | PackageItemInfo.SAFE_LABEL_FLAG_FIRST_LINE).toString());
70             CharSequence app2 = BidiFormatter.getInstance().unicodeWrap(pm.getApplicationInfo(
71                     mProviderPkg, 0).loadSafeLabel(pm, PackageItemInfo.DEFAULT_MAX_LABEL_SIZE_PX,
72                     PackageItemInfo.SAFE_LABEL_FLAG_TRIM
73                             | PackageItemInfo.SAFE_LABEL_FLAG_FIRST_LINE).toString());
74             AlertDialog dialog = new AlertDialog.Builder(this)
75                     .setTitle(getString(R.string.slice_permission_title, app1, app2))
76                     .setView(R.layout.slice_permission_request)
77                     .setNegativeButton(R.string.slice_permission_deny, this)
78                     .setPositiveButton(R.string.slice_permission_allow, this)
79                     .setOnDismissListener(this)
80                     .create();
81             dialog.getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
82             dialog.show();
83             TextView t1 = dialog.getWindow().getDecorView().findViewById(R.id.text1);
84             t1.setText(getString(R.string.slice_permission_text_1, app2));
85             TextView t2 = dialog.getWindow().getDecorView().findViewById(R.id.text2);
86             t2.setText(getString(R.string.slice_permission_text_2, app2));
87             mAllCheckbox = dialog.getWindow().getDecorView().findViewById(
88                     R.id.slice_permission_checkbox);
89             mAllCheckbox.setText(getString(R.string.slice_permission_checkbox, app1));
90         } catch (NameNotFoundException e) {
91             Log.e(TAG, "Couldn't find package", e);
92             finish();
93         }
94     }
95 
96     @Override
onClick(DialogInterface dialog, int which)97     public void onClick(DialogInterface dialog, int which) {
98         if (which == DialogInterface.BUTTON_POSITIVE) {
99             getSystemService(SliceManager.class).grantPermissionFromUser(mUri, mCallingPkg,
100                     mAllCheckbox.isChecked());
101         }
102         finish();
103     }
104 
105     @Override
onDismiss(DialogInterface dialog)106     public void onDismiss(DialogInterface dialog) {
107         finish();
108     }
109 
verifyCallingPkg()110     private void verifyCallingPkg() {
111         final String providerPkg = getIntent().getStringExtra("provider_pkg");
112         if (providerPkg == null || mProviderPkg.equals(providerPkg)) return;
113         final String callingPkg = getCallingPkg();
114         EventLog.writeEvent(0x534e4554, "159145361", getUid(callingPkg));
115     }
116 
117     @Nullable
getCallingPkg()118     private String getCallingPkg() {
119         final Uri referrer = getReferrer();
120         if (referrer == null) return null;
121         return referrer.getHost();
122     }
123 
getUid(@ullable final String pkg)124     private int getUid(@Nullable final String pkg) {
125         if (pkg == null) return -1;
126         try {
127             return getPackageManager().getApplicationInfo(pkg, 0).uid;
128         } catch (NameNotFoundException e) {
129         }
130         return -1;
131     }
132 }
133