1 /*
2  * Copyright (C) 2015 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;
18 
19 import static android.health.connect.HealthPermissions.HEALTH_PERMISSION_GROUP;
20 import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
21 
22 import static com.android.permissioncontroller.Constants.ACTION_MANAGE_AUTO_REVOKE;
23 import static com.android.permissioncontroller.Constants.EXTRA_SESSION_ID;
24 import static com.android.permissioncontroller.Constants.INVALID_SESSION_ID;
25 import static com.android.permissioncontroller.Constants.UNUSED_APPS_SAFETY_CENTER_SOURCE_ID;
26 import static com.android.permissioncontroller.PermissionControllerStatsLog.APP_PERMISSION_GROUPS_FRAGMENT_AUTO_REVOKE_ACTION;
27 import static com.android.permissioncontroller.PermissionControllerStatsLog.APP_PERMISSION_GROUPS_FRAGMENT_AUTO_REVOKE_ACTION__ACTION__OPENED_FOR_AUTO_REVOKE;
28 import static com.android.permissioncontroller.PermissionControllerStatsLog.APP_PERMISSION_GROUPS_FRAGMENT_AUTO_REVOKE_ACTION__ACTION__OPENED_FROM_INTENT;
29 import static com.android.permissioncontroller.PermissionControllerStatsLog.AUTO_REVOKE_NOTIFICATION_CLICKED;
30 import static com.android.permissioncontroller.PermissionControllerStatsLog.PERMISSION_USAGE_FRAGMENT_INTERACTION;
31 import static com.android.permissioncontroller.PermissionControllerStatsLog.PERMISSION_USAGE_FRAGMENT_INTERACTION__ACTION__OPEN;
32 
33 import android.Manifest;
34 import android.annotation.TargetApi;
35 import android.content.ComponentName;
36 import android.content.Intent;
37 import android.content.pm.PackageManager;
38 import android.content.pm.PackageManager.NameNotFoundException;
39 import android.content.pm.PermissionInfo;
40 import android.os.Build;
41 import android.os.Bundle;
42 import android.os.Process;
43 import android.os.UserHandle;
44 import android.permission.PermissionManager;
45 import android.provider.Settings;
46 import android.safetycenter.SafetyCenterManager;
47 import android.safetycenter.SafetyEvent;
48 import android.safetycenter.SafetySourceData;
49 import android.util.Log;
50 import android.view.MenuItem;
51 
52 import androidx.fragment.app.Fragment;
53 import androidx.navigation.NavGraph;
54 import androidx.navigation.NavInflater;
55 import androidx.navigation.Navigation;
56 import androidx.navigation.fragment.NavHostFragment;
57 
58 import com.android.modules.utils.build.SdkLevel;
59 import com.android.permissioncontroller.Constants;
60 import com.android.permissioncontroller.DeviceUtils;
61 import com.android.permissioncontroller.PermissionControllerStatsLog;
62 import com.android.permissioncontroller.R;
63 import com.android.permissioncontroller.hibernation.HibernationPolicyKt;
64 import com.android.permissioncontroller.permission.ui.auto.AutoAllAppPermissionsFragment;
65 import com.android.permissioncontroller.permission.ui.auto.AutoAppPermissionsFragment;
66 import com.android.permissioncontroller.permission.ui.auto.AutoManageStandardPermissionsFragment;
67 import com.android.permissioncontroller.permission.ui.auto.AutoPermissionAppsFragment;
68 import com.android.permissioncontroller.permission.ui.auto.AutoReviewPermissionDecisionsFragment;
69 import com.android.permissioncontroller.permission.ui.auto.AutoUnusedAppsFragment;
70 import com.android.permissioncontroller.permission.ui.auto.dashboard.AutoPermissionUsageDetailsFragment;
71 import com.android.permissioncontroller.permission.ui.auto.dashboard.AutoPermissionUsageFragment;
72 import com.android.permissioncontroller.permission.ui.handheld.AppPermissionFragment;
73 import com.android.permissioncontroller.permission.ui.handheld.AppPermissionGroupsFragment;
74 import com.android.permissioncontroller.permission.ui.handheld.PermissionAppsFragment;
75 import com.android.permissioncontroller.permission.ui.handheld.v31.PermissionDetailsWrapperFragment;
76 import com.android.permissioncontroller.permission.ui.handheld.v31.PermissionUsageWrapperFragment;
77 import com.android.permissioncontroller.permission.ui.handheld.v34.AppDataSharingUpdatesFragment;
78 import com.android.permissioncontroller.permission.ui.legacy.AppPermissionActivity;
79 import com.android.permissioncontroller.permission.ui.television.TvUnusedAppsFragment;
80 import com.android.permissioncontroller.permission.ui.wear.WearAppPermissionFragment;
81 import com.android.permissioncontroller.permission.ui.wear.WearPermissionUsageDetailsFragment;
82 import com.android.permissioncontroller.permission.ui.wear.WearPermissionUsageFragment;
83 import com.android.permissioncontroller.permission.ui.wear.WearUnusedAppsFragment;
84 import com.android.permissioncontroller.permission.utils.KotlinUtils;
85 import com.android.permissioncontroller.permission.utils.PermissionMapping;
86 import com.android.permissioncontroller.permission.utils.Utils;
87 
88 import java.util.Objects;
89 import java.util.Random;
90 
91 /**
92  * Activity to review and manage permissions
93  */
94 public final class ManagePermissionsActivity extends SettingsActivity {
95     private static final String LOG_TAG = ManagePermissionsActivity.class.getSimpleName();
96 
97     /**
98      * Name of the extra parameter that indicates whether or not to show all app permissions
99      */
100     public static final String EXTRA_ALL_PERMISSIONS =
101             "com.android.permissioncontroller.extra.ALL_PERMISSIONS";
102 
103     /**
104      * Name of the extra parameter that is the fragment that called the current fragment.
105      */
106     public static final String EXTRA_CALLER_NAME =
107             "com.android.permissioncontroller.extra.CALLER_NAME";
108 
109     // The permission group which was interacted with
110     public static final String EXTRA_RESULT_PERMISSION_INTERACTED = "com.android"
111             + ".permissioncontroller.extra.RESULT_PERMISSION_INTERACTED";
112     /**
113      * The result of the permission in terms of {@link GrantPermissionsViewHandler.Result}
114      */
115     public static final String EXTRA_RESULT_PERMISSION_RESULT = "com.android"
116             + ".permissioncontroller.extra.PERMISSION_RESULT";
117 
118     /**
119      * Whether to show system apps in UI receiving an intent containing this extra.
120      */
121     public static final String EXTRA_SHOW_SYSTEM = "com.android"
122             + ".permissioncontroller.extra.SHOW_SYSTEM";
123 
124     /**
125      * Whether to show 7 days permission usage data in UI receiving an intent containing this extra.
126      */
127     public static final String EXTRA_SHOW_7_DAYS = "com.android"
128             + ".permissioncontroller.extra.SHOW_7_DAYS";
129 
130     /**
131      * Name of the aliased activity.
132      */
133     public static final String ALIAS_ACTIVITY_NAME =
134             "com.android.permissioncontroller.permission.ui.ManagePermissionsActivityAlias";
135 
136     /**
137      * The requestCode used when we decide not to use this activity, but instead launch
138      * another activity in our place. When that activity finishes, we set it's result
139      * as our result and then finish.
140      */
141     private static final int PROXY_ACTIVITY_REQUEST_CODE = 5;
142 
143     @TargetApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
144     private static final String LAUNCH_PERMISSION_SETTINGS =
145             Manifest.permission.LAUNCH_PERMISSION_SETTINGS;
146 
147     @TargetApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
148     private static final String APP_PERMISSIONS_SETTINGS = Settings.ACTION_APP_PERMISSIONS_SETTINGS;
149 
150     @Override
onCreate(Bundle savedInstanceState)151     public void onCreate(Bundle savedInstanceState) {
152         if (DeviceUtils.isAuto(this)) {
153             // Automotive relies on a different theme. Apply before calling super so that
154             // fragments are restored properly on configuration changes.
155             setTheme(R.style.CarSettings);
156         }
157         super.onCreate(savedInstanceState);
158 
159         // TODO(b/309578419): Make this activity handle insets properly and then remove this.
160         getTheme().applyStyle(R.style.OptOutEdgeToEdgeEnforcement, /* force */ false);
161 
162         // If this is not a phone or a watch (which uses the Navigation component), and there
163         // is a previous instance, re-use its Fragment instead of making a new one.
164         if ((DeviceUtils.isTelevision(this) || DeviceUtils.isAuto(this))
165                 && savedInstanceState != null) {
166             return;
167         }
168 
169         boolean provisioned = Settings.Global.getInt(
170                 getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0) != 0;
171         boolean completed = Settings.Secure.getInt(
172                 getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, 0) != 0;
173         if (!provisioned || !completed) {
174             Log.e(LOG_TAG, "Device setup incomplete. device provisioned=" + provisioned
175                     + ", user setup complete=" + completed);
176             finishAfterTransition();
177             return;
178         }
179 
180         android.app.Fragment fragment = null;
181         Fragment androidXFragment = null;
182         String action = getIntent().getAction();
183 
184         getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
185 
186         long sessionId = getIntent().getLongExtra(Constants.EXTRA_SESSION_ID, INVALID_SESSION_ID);
187         while (sessionId == INVALID_SESSION_ID) {
188             sessionId = new Random().nextLong();
189         }
190 
191         int autoRevokeAction =
192                 APP_PERMISSION_GROUPS_FRAGMENT_AUTO_REVOKE_ACTION__ACTION__OPENED_FOR_AUTO_REVOKE;
193         int openFromIntentAction =
194                 APP_PERMISSION_GROUPS_FRAGMENT_AUTO_REVOKE_ACTION__ACTION__OPENED_FROM_INTENT;
195 
196         ComponentName component = getIntent().getComponent();
197         if (component != null
198                 && Objects.equals(component.getClassName(), ALIAS_ACTIVITY_NAME)
199                 && !Objects.equals(action, APP_PERMISSIONS_SETTINGS)) {
200             Log.w(LOG_TAG, ALIAS_ACTIVITY_NAME + " can only be launched with "
201                             + APP_PERMISSIONS_SETTINGS);
202             finishAfterTransition();
203             return;
204         }
205 
206         String permissionName;
207         switch (action) {
208             case Intent.ACTION_MANAGE_PERMISSIONS:
209                 Bundle arguments = new Bundle();
210                 arguments.putLong(EXTRA_SESSION_ID, sessionId);
211                 if (DeviceUtils.isAuto(this)) {
212                     androidXFragment = AutoManageStandardPermissionsFragment.newInstance();
213                     androidXFragment.setArguments(arguments);
214                 } else if (DeviceUtils.isTelevision(this)) {
215                     androidXFragment =
216                             com.android.permissioncontroller.permission.ui.television
217                                     .ManagePermissionsFragment.newInstance();
218                 } else {
219                     setContentView(R.layout.nav_host_fragment);
220                     Navigation.findNavController(this, R.id.nav_host_fragment).setGraph(
221                             R.navigation.nav_graph, arguments);
222                     return;
223 
224                 }
225                 break;
226 
227             case Intent.ACTION_REVIEW_PERMISSION_USAGE: {
228                 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
229                     finishAfterTransition();
230                     return;
231                 }
232 
233                 PermissionControllerStatsLog.write(PERMISSION_USAGE_FRAGMENT_INTERACTION, sessionId,
234                         PERMISSION_USAGE_FRAGMENT_INTERACTION__ACTION__OPEN);
235                 if (DeviceUtils.isAuto(this)) {
236                     androidXFragment = new AutoPermissionUsageFragment();
237                 } else if (DeviceUtils.isWear(this)) {
238                     androidXFragment = WearPermissionUsageFragment.newInstance(sessionId);
239                 } else {
240                     androidXFragment = PermissionUsageWrapperFragment.newInstance(
241                             Long.MAX_VALUE, sessionId);
242                 }
243             } break;
244 
245             case Intent.ACTION_REVIEW_PERMISSION_HISTORY: {
246                 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
247                     finishAfterTransition();
248                     return;
249                 }
250 
251                 String groupName = getIntent()
252                         .getStringExtra(Intent.EXTRA_PERMISSION_GROUP_NAME);
253                 boolean showSystem = getIntent()
254                         .getBooleanExtra(EXTRA_SHOW_SYSTEM, false);
255                 boolean show7Days = getIntent()
256                         .getBooleanExtra(EXTRA_SHOW_7_DAYS, false);
257                 if (DeviceUtils.isAuto(this)) {
258                     androidXFragment = AutoPermissionUsageDetailsFragment.Companion.newInstance(
259                             groupName, showSystem, sessionId);
260                 } else if (DeviceUtils.isWear(this)) {
261                     androidXFragment = WearPermissionUsageDetailsFragment
262                             .newInstance(groupName, showSystem, show7Days);
263                 } else {
264                     androidXFragment = PermissionDetailsWrapperFragment
265                             .newInstance(groupName, Long.MAX_VALUE, showSystem, sessionId,
266                                     show7Days);
267                 }
268                 break;
269             }
270 
271             case Intent.ACTION_MANAGE_APP_PERMISSION: {
272                 if (DeviceUtils.isAuto(this) || DeviceUtils.isTelevision(this)) {
273                     Intent compatIntent = new Intent(this, AppPermissionActivity.class);
274                     compatIntent.putExtras(getIntent().getExtras());
275                     startActivityForResult(compatIntent, PROXY_ACTIVITY_REQUEST_CODE);
276                     return;
277                 }
278                 String packageName = getIntent().getStringExtra(Intent.EXTRA_PACKAGE_NAME);
279 
280                 if (packageName == null) {
281                     Log.i(LOG_TAG, "Missing mandatory argument EXTRA_PACKAGE_NAME");
282                     finishAfterTransition();
283                     return;
284                 }
285                 permissionName = getIntent().getStringExtra(Intent.EXTRA_PERMISSION_NAME);
286                 String groupName = getIntent().getStringExtra(Intent.EXTRA_PERMISSION_GROUP_NAME);
287 
288                 if (permissionName == null && groupName == null) {
289                     Log.i(LOG_TAG, "Missing mandatory argument EXTRA_PERMISSION_NAME or"
290                             + "EXTRA_PERMISSION_GROUP_NAME");
291                     finishAfterTransition();
292                     return;
293                 }
294 
295                 UserHandle userHandle = getIntent().getParcelableExtra(Intent.EXTRA_USER);
296                 String caller = getIntent().getStringExtra(EXTRA_CALLER_NAME);
297 
298                 if (groupName == null) {
299                     groupName = getGroupFromPermission(permissionName);
300                 }
301 
302                 if (groupName != null
303                         && groupName.equals(Manifest.permission_group.NOTIFICATIONS)) {
304                     // Redirect notification group to notification settings
305                     Utils.navigateToAppNotificationSettings(this, packageName, userHandle);
306                     finishAfterTransition();
307                     return;
308                 }
309 
310                 Bundle args;
311                 if (DeviceUtils.isWear(this)) {
312                     args = WearAppPermissionFragment.createArgs(packageName, permissionName,
313                             groupName, userHandle, caller, sessionId, null);
314                 } else {
315                     args = AppPermissionFragment.createArgs(packageName, permissionName,
316                             groupName, userHandle, caller, sessionId, null);
317                 }
318                 setNavGraph(args, R.id.app_permission);
319                 return;
320             }
321 
322             case Intent.ACTION_MANAGE_APP_PERMISSIONS:
323             case APP_PERMISSIONS_SETTINGS: {
324                 if (!SdkLevel.isAtLeastV()
325                         && Objects.equals(action, APP_PERMISSIONS_SETTINGS)) {
326                     PermissionInfo permissionInfo;
327                     try {
328                         permissionInfo = getPackageManager()
329                                 .getPermissionInfo(LAUNCH_PERMISSION_SETTINGS, 0);
330                     } catch (NameNotFoundException e) {
331                         permissionInfo = null;
332                     }
333                     if (permissionInfo == null
334                             || !Objects.equals(permissionInfo.packageName, Utils.OS_PKG)) {
335                         Log.w(LOG_TAG, LAUNCH_PERMISSION_SETTINGS
336                                 + " must be defined by platform.");
337                         finishAfterTransition();
338                         return;
339                     }
340                 }
341 
342                 String packageName = getIntent().getStringExtra(Intent.EXTRA_PACKAGE_NAME);
343                 if (packageName == null) {
344                     Log.i(LOG_TAG, "Missing mandatory argument EXTRA_PACKAGE_NAME");
345                     finishAfterTransition();
346                     return;
347                 }
348 
349                 UserHandle userHandle = getIntent().getParcelableExtra(Intent.EXTRA_USER);
350                 if (userHandle == null) {
351                     userHandle = Process.myUserHandle();
352                 }
353 
354                 try {
355                     int uid = getPackageManager().getApplicationInfoAsUser(packageName, 0,
356                             userHandle).uid;
357                     long settingsSessionId = getIntent().getLongExtra(
358                             Intent.ACTION_AUTO_REVOKE_PERMISSIONS, INVALID_SESSION_ID);
359                     if (settingsSessionId != INVALID_SESSION_ID) {
360                         sessionId = settingsSessionId;
361                         Log.i(LOG_TAG, "sessionId: " + sessionId
362                                 + " Reaching AppPermissionGroupsFragment for auto revoke. "
363                                 + "packageName: " + packageName + " uid " + uid);
364                         PermissionControllerStatsLog.write(
365                                 APP_PERMISSION_GROUPS_FRAGMENT_AUTO_REVOKE_ACTION, sessionId, uid,
366                                 packageName, autoRevokeAction);
367                     } else {
368                         if (KotlinUtils.INSTANCE.isROrAutoRevokeEnabled(getApplication(),
369                                 packageName, userHandle)) {
370                             Log.i(LOG_TAG, "sessionId: " + sessionId
371                                     + " Reaching AppPermissionGroupsFragment from intent. "
372                                     + "packageName " + packageName + " uid " + uid);
373                             PermissionControllerStatsLog.write(
374                                     APP_PERMISSION_GROUPS_FRAGMENT_AUTO_REVOKE_ACTION, sessionId,
375                                     uid, packageName, openFromIntentAction);
376                         }
377                     }
378                 } catch (PackageManager.NameNotFoundException e) {
379                     // Do no logging
380                 }
381 
382                 final boolean allPermissions = getIntent().getBooleanExtra(
383                         EXTRA_ALL_PERMISSIONS, false);
384 
385 
386                 if (DeviceUtils.isAuto(this)) {
387                     if (allPermissions) {
388                         androidXFragment = AutoAllAppPermissionsFragment.newInstance(packageName,
389                                 userHandle, sessionId);
390                     } else {
391                         androidXFragment = AutoAppPermissionsFragment.newInstance(packageName,
392                                 userHandle, sessionId, /* isSystemPermsScreen= */ true);
393                     }
394                 } else if (DeviceUtils.isTelevision(this)) {
395                     androidXFragment = com.android.permissioncontroller.permission.ui.television
396                             .AppPermissionsFragment.newInstance(packageName, userHandle);
397                 } else {
398                     Bundle args = AppPermissionGroupsFragment.createArgs(packageName, userHandle,
399                             sessionId, /* isSystemPermsScreen= */  true);
400                     setNavGraph(args, R.id.app_permission_groups);
401                     return;
402                 }
403                 break;
404             }
405 
406             case Intent.ACTION_MANAGE_PERMISSION_APPS: {
407                 permissionName = getIntent().getStringExtra(Intent.EXTRA_PERMISSION_NAME);
408 
409                 String permissionGroupName = getIntent().getStringExtra(
410                         Intent.EXTRA_PERMISSION_GROUP_NAME);
411 
412                 if (permissionGroupName == null) {
413                     try {
414                         PermissionInfo permInfo = getPackageManager().getPermissionInfo(
415                                 permissionName, 0);
416                         permissionGroupName = PermissionMapping.getGroupOfPermission(permInfo);
417                     } catch (PackageManager.NameNotFoundException e) {
418                         Log.i(LOG_TAG, "Permission " + permissionName + " does not exist");
419                     }
420                 }
421 
422                 if (permissionGroupName == null) {
423                     permissionGroupName = permissionName;
424                 }
425 
426                 if (permissionName == null && permissionGroupName == null) {
427                     Log.i(LOG_TAG, "Missing mandatory argument EXTRA_PERMISSION_NAME or"
428                             + "EXTRA_PERMISSION_GROUP_NAME");
429                     finishAfterTransition();
430                     return;
431                 }
432 
433                 // Redirect notification group to notification settings
434                 if (permissionGroupName.equals(Manifest.permission_group.NOTIFICATIONS)) {
435                     Utils.navigateToNotificationSettings(this);
436                     finishAfterTransition();
437                     return;
438                 }
439 
440                 if (Utils.isHealthPermissionUiEnabled() && permissionGroupName
441                                 .equals(HEALTH_PERMISSION_GROUP)) {
442                     Utils.navigateToHealthConnectSettings(this);
443                     finishAfterTransition();
444                     return;
445                 }
446 
447                 if (DeviceUtils.isAuto(this)) {
448                     androidXFragment =
449                             AutoPermissionAppsFragment.newInstance(permissionGroupName, sessionId);
450                 } else if (DeviceUtils.isTelevision(this)) {
451                     androidXFragment = com.android.permissioncontroller.permission.ui.television
452                             .PermissionAppsFragment.newInstance(permissionGroupName);
453                 } else {
454                     Bundle args = PermissionAppsFragment.createArgs(permissionGroupName, sessionId);
455                     setNavGraph(args, R.id.permission_apps);
456                     return;
457                 }
458             } break;
459 
460             case Intent.ACTION_MANAGE_UNUSED_APPS :
461                 // fall through
462             case ACTION_MANAGE_AUTO_REVOKE: {
463                 Log.i(LOG_TAG, "sessionId " + sessionId + " starting auto revoke fragment"
464                         + " from notification");
465                 PermissionControllerStatsLog.write(AUTO_REVOKE_NOTIFICATION_CLICKED, sessionId);
466                 if (SdkLevel.isAtLeastT()) {
467                     SafetyCenterManager safetyCenterManager =
468                             getSystemService(SafetyCenterManager.class);
469                     if (safetyCenterManager.isSafetyCenterEnabled()) {
470                         SafetySourceData data = safetyCenterManager.getSafetySourceData(
471                                 UNUSED_APPS_SAFETY_CENTER_SOURCE_ID);
472                         if (data != null && !data.getIssues().isEmpty()) {
473                             // Clear source data as user has reviewed their unused apps
474                             HibernationPolicyKt.setUnusedAppsReviewNeeded(this, false);
475                             HibernationPolicyKt.rescanAndPushDataToSafetyCenter(this, sessionId,
476                                     new SafetyEvent.Builder(
477                                             SafetyEvent.SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED)
478                                             .build());
479                             HibernationPolicyKt.cancelUnusedAppsNotification(this);
480                         }
481                     }
482                 }
483 
484                 if (DeviceUtils.isAuto(this)) {
485                     androidXFragment = AutoUnusedAppsFragment.newInstance();
486                     androidXFragment.setArguments(UnusedAppsFragment.createArgs(sessionId));
487                 } else if (DeviceUtils.isTelevision(this)) {
488                     androidXFragment = TvUnusedAppsFragment.newInstance();
489                     androidXFragment.setArguments(UnusedAppsFragment.createArgs(sessionId));
490                 } else if (DeviceUtils.isWear(this)) {
491                     setNavGraph(WearUnusedAppsFragment.createArgs(sessionId), R.id.auto_revoke);
492                     return;
493                 } else {
494                     setNavGraph(UnusedAppsFragment.createArgs(sessionId), R.id.auto_revoke);
495                     return;
496                 }
497 
498                 break;
499             }
500             case PermissionManager.ACTION_REVIEW_PERMISSION_DECISIONS: {
501 
502                 UserHandle userHandle = getIntent().getParcelableExtra(Intent.EXTRA_USER);
503                 if (userHandle == null) {
504                     userHandle = Process.myUserHandle();
505                 }
506                 if (DeviceUtils.isAuto(this)) {
507                     String source = getIntent().getStringExtra(
508                             AutoReviewPermissionDecisionsFragment.EXTRA_SOURCE);
509                     androidXFragment = AutoReviewPermissionDecisionsFragment.Companion
510                             .newInstance(sessionId, userHandle, source);
511                 } else {
512                     Log.e(LOG_TAG, "ACTION_REVIEW_PERMISSION_DECISIONS is not "
513                             + "supported on this device type");
514                     finishAfterTransition();
515                     return;
516                 }
517             } break;
518 
519             case Intent.ACTION_REVIEW_APP_DATA_SHARING_UPDATES: {
520                 if (KotlinUtils.INSTANCE.isSafetyLabelChangeNotificationsEnabled(this)) {
521                     setNavGraph(AppDataSharingUpdatesFragment.Companion.createArgs(sessionId),
522                             R.id.app_data_sharing_updates);
523                 } else {
524                     finishAfterTransition();
525                     return;
526                 }
527             } break;
528 
529             default: {
530                 Log.w(LOG_TAG, "Unrecognized action " + action);
531                 finishAfterTransition();
532                 return;
533             }
534         }
535 
536         if (fragment != null) {
537             getFragmentManager().beginTransaction().replace(android.R.id.content, fragment)
538                     .commit();
539         } else if (androidXFragment != null) {
540             getSupportFragmentManager().beginTransaction().replace(android.R.id.content,
541                     androidXFragment).commit();
542         }
543     }
544 
getGroupFromPermission(String permissionName)545     private String getGroupFromPermission(String permissionName) {
546         try {
547             PermissionInfo permInfo = getPackageManager().getPermissionInfo(
548                     permissionName, 0);
549             return PermissionMapping.getGroupOfPermission(permInfo);
550         } catch (PackageManager.NameNotFoundException e) {
551             Log.i(LOG_TAG, "Permission " + permissionName + " does not exist");
552         }
553         return null;
554     }
555 
setNavGraph(Bundle args, int startDestination)556     private void setNavGraph(Bundle args, int startDestination) {
557         setContentView(R.layout.nav_host_fragment);
558         NavHostFragment navHost = (NavHostFragment) getSupportFragmentManager()
559                 .findFragmentById(R.id.nav_host_fragment);
560         NavInflater inflater = navHost.getNavController().getNavInflater();
561         NavGraph graph = inflater.inflate(R.navigation.nav_graph);
562         graph.setStartDestination(startDestination);
563         navHost.getNavController().setGraph(graph, args);
564     }
565 
566     @Override
onOptionsItemSelected(MenuItem item)567     public boolean onOptionsItemSelected(MenuItem item) {
568         // in automotive mode, there's no system wide back button, so need to add that
569         if (DeviceUtils.isAuto(this)) {
570             switch (item.getItemId()) {
571                 case android.R.id.home:
572                     onBackPressed();
573                     finishAfterTransition();
574                     return true;
575                 default:
576                     return super.onOptionsItemSelected(item);
577             }
578         }
579         return super.onOptionsItemSelected(item);
580     }
581 
582     @Override
onActivityResult(int requestCode, int resultCode, Intent data)583     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
584         super.onActivityResult(requestCode, resultCode, data);
585         if (requestCode == PROXY_ACTIVITY_REQUEST_CODE) {
586             setResult(resultCode, data);
587             finishAfterTransition();
588         }
589     }
590 
591 }
592