1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.permissioncontroller.permission.ui.legacy;
18 
19 import static android.content.Intent.ACTION_MANAGE_APP_PERMISSION;
20 import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
21 
22 import android.content.Intent;
23 import android.content.pm.PackageManager;
24 import android.content.pm.PermissionGroupInfo;
25 import android.content.pm.PermissionInfo;
26 import android.os.Bundle;
27 import android.os.UserHandle;
28 import android.util.Log;
29 import android.view.MenuItem;
30 
31 import androidx.fragment.app.Fragment;
32 import androidx.fragment.app.FragmentActivity;
33 
34 import com.android.permissioncontroller.DeviceUtils;
35 import com.android.permissioncontroller.R;
36 import com.android.permissioncontroller.permission.ui.GrantPermissionsViewHandler;
37 import com.android.permissioncontroller.permission.ui.LocationProviderInterceptDialog;
38 import com.android.permissioncontroller.permission.ui.ManagePermissionsActivity;
39 import com.android.permissioncontroller.permission.ui.auto.AutoAppPermissionFragment;
40 import com.android.permissioncontroller.permission.ui.television.AppPermissionFragment;
41 import com.android.permissioncontroller.permission.utils.LocationUtils;
42 import com.android.permissioncontroller.permission.utils.Utils;
43 
44 import java.util.List;
45 
46 /**
47  * Manage a single permission of a single app.
48  *
49  * @deprecated This class is deprecated for handheld UI, and will throw an error if used for
50  * handheld (read: non auto, TV, or wear) UIs. Instead, users should create an intent with the
51  * ACTION_MANAGE_APP_PERMISSION action, which will intent into the ManagePermissionsActivity.
52  *
53  * @see ManagePermissionsActivity
54  */
55 @Deprecated
56 public final class AppPermissionActivity extends FragmentActivity {
57     private static final String LOG_TAG = AppPermissionActivity.class.getSimpleName();
58 
59     public static final String EXTRA_CALLER_NAME =
60             "com.android.permissioncontroller.extra.CALLER_NAME";
61 
62     // The permission group which was interacted with
63     public static final String EXTRA_RESULT_PERMISSION_INTERACTED = "com.android"
64             + ".permissioncontroller.extra.RESULT_PERMISSION_INTERACTED";
65     /**
66      * The result of the permission in terms of {@link GrantPermissionsViewHandler.Result}
67      */
68     public static final String EXTRA_RESULT_PERMISSION_RESULT = "com.android"
69             + ".permissioncontroller.extra.PERMISSION_RESULT";
70 
71     @Override
onCreate(Bundle savedInstanceState)72     public void onCreate(Bundle savedInstanceState) {
73         if (!DeviceUtils.isAuto(this) && !DeviceUtils.isWear(this)
74                 && !DeviceUtils.isTelevision(this)) {
75             throw new IllegalStateException("Do not use AppPermissionActivity for handheld ui. "
76                     + "Create intent with ACTION_MANAGE_APP_PERMISSION instead.");
77         }
78         if (DeviceUtils.isAuto(this)) {
79             // Automotive relies on a different theme. Apply before calling super so that
80             // fragments are restored properly on configuration changes.
81             setTheme(R.style.CarSettings);
82         }
83         super.onCreate(savedInstanceState);
84 
85         getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
86 
87         String packageName = getIntent().getStringExtra(Intent.EXTRA_PACKAGE_NAME);
88         if (packageName == null) {
89             Log.e(LOG_TAG, "Missing mandatory argument EXTRA_PACKAGE_NAME");
90             finish();
91             return;
92         }
93 
94         String permissionName = getIntent().getStringExtra(Intent.EXTRA_PERMISSION_NAME);
95         String groupName = getIntent().getStringExtra(Intent.EXTRA_PERMISSION_GROUP_NAME);
96         if (permissionName == null && groupName == null) {
97             Log.e(LOG_TAG, "Missing argument EXTRA_PERMISSION_NAME or "
98                     + "EXTRA_PERMISSION_GROUP_NAME, at least one must be present.");
99             finish();
100             return;
101         }
102         if (groupName == null) {
103             groupName = Utils.getGroupOfPlatformPermission(permissionName);
104             PermissionInfo permission;
105             try {
106                 permission = getPackageManager().getPermissionInfo(permissionName, 0);
107                 if (!permission.packageName.equals(Utils.OS_PKG)) {
108                     List<PermissionGroupInfo> groupInfos =
109                             getPackageManager().getAllPermissionGroups(0);
110                     for (PermissionGroupInfo groupInfo : groupInfos) {
111                         if (groupInfo.name.equals(permission.group)) {
112                             groupName = permission.group;
113                         }
114                     }
115 
116                 }
117             } catch (PackageManager.NameNotFoundException e) {
118                 groupName = null;
119             }
120         }
121 
122         UserHandle userHandle = getIntent().getParcelableExtra(Intent.EXTRA_USER);
123         if (userHandle == null) {
124             Log.e(LOG_TAG, "Missing mandatory argument EXTRA_USER");
125             finish();
126             return;
127         }
128 
129         if (LocationUtils.isLocationGroupAndProvider(this, groupName,
130                 packageName)) {
131             Intent intent = new Intent(this, LocationProviderInterceptDialog.class);
132             intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
133             startActivityAsUser(intent, userHandle);
134             finish();
135             return;
136         }
137 
138         if (LocationUtils.isLocationGroupAndControllerExtraPackage(
139                 this, groupName, packageName)) {
140             // Redirect to location controller extra package settings.
141             LocationUtils.startLocationControllerExtraPackageSettings(this, userHandle);
142             finish();
143             return;
144         }
145 
146         if (DeviceUtils.isAuto(this)) {
147             Fragment androidXFragment;
148 
149             androidXFragment = AutoAppPermissionFragment.newInstance(packageName, permissionName,
150                     groupName, userHandle);
151 
152             getSupportFragmentManager().beginTransaction().replace(android.R.id.content,
153                     androidXFragment).commit();
154         } else if (DeviceUtils.isTelevision(this)) {
155             Fragment androidXFragment = new AppPermissionFragment();
156             androidXFragment.setArguments(
157                     AppPermissionFragment.createArgs(
158                             packageName, permissionName, groupName, userHandle, null, 0, null));
159             getSupportFragmentManager().beginTransaction()
160                     .replace(android.R.id.content, androidXFragment)
161                     .commit();
162         } else {
163             startActivity(new Intent(getIntent()).setAction(ACTION_MANAGE_APP_PERMISSION));
164             finish();
165         }
166     }
167 
168     @Override
onOptionsItemSelected(MenuItem item)169     public boolean onOptionsItemSelected(MenuItem item) {
170         // in automotive mode, there's no system wide back button, so need to add that
171         if (DeviceUtils.isAuto(this)) {
172             switch (item.getItemId()) {
173                 case android.R.id.home:
174                     onBackPressed();
175                     return true;
176                 default:
177                     return super.onOptionsItemSelected(item);
178             }
179         }
180         return super.onOptionsItemSelected(item);
181     }
182 }
183