public InstallPermissionTester()

in niap-cc/Permissions/Tester/app/src/main/java/com/android/certifications/niap/permissions/InstallPermissionTester.java [139:534]


    public InstallPermissionTester(TestConfiguration configuration, Activity activity) {
        super(configuration, activity);

        mConnectivityManager = (ConnectivityManager) mContext.getSystemService(
                Context.CONNECTIVITY_SERVICE);
        mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
        mBluetoothManager = (BluetoothManager) mContext.getSystemService(Context.BLUETOOTH_SERVICE);
        mBluetoothAdapter = mBluetoothManager.getAdapter();
        mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
        mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
        mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
        mPackageInstaller = mPackageManager.getPackageInstaller();
        mDevicePolicyManager = (DevicePolicyManager) mContext.getSystemService(
                Context.DEVICE_POLICY_SERVICE);
        mWallpaperManager = (WallpaperManager) mContext.getSystemService(Context.WALLPAPER_SERVICE);
        mConsumerIrManager = (ConsumerIrManager) mContext.getSystemService(
                Context.CONSUMER_IR_SERVICE);
        mVibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
        mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);

        mPermissionTasks = new HashMap<>();

        mPermissionTasks.put(ACCESS_NETWORK_STATE,
                new PermissionTest(false, () -> mConnectivityManager.getActiveNetwork()));

        mPermissionTasks.put(ACCESS_WIFI_STATE,
                new PermissionTest(false, () -> mWifiManager.getConfiguredNetworks()));

        // android.permission.AUTHENTICATE_ACCOUNTS has been removed.

        mPermissionTasks.put(BLUETOOTH, new PermissionTest(false, () -> {
            if (mBluetoothAdapter == null) {
                throw new BypassTestException(
                        "A bluetooth adapter is not available to run this test");
            }
            mBluetoothAdapter.getAddress();
        }));

        mPermissionTasks.put(BLUETOOTH_ADMIN, new PermissionTest(false, () -> {
            if (mBluetoothAdapter == null) {
                throw new BypassTestException(
                        "A bluetooth adapter is not available to run this test");
            }
            if (mBluetoothAdapter.isEnabled()) {
                mBluetoothAdapter.disable();
                mBluetoothAdapter.enable();
            } else {
                mBluetoothAdapter.enable();
            }
        }));

        mPermissionTasks.put(BROADCAST_STICKY, new PermissionTest(false, () -> {
            Intent intent = new Intent();
            mContext.sendStickyBroadcast(intent);
        }));

        // android.permission.CALL_COMPANION_APP requires an active call.

        mPermissionTasks.put(CHANGE_NETWORK_STATE, new PermissionTest(false, () -> {
            NetworkRequest networkRequest = new NetworkRequest.Builder().addCapability(
                    NetworkCapabilities.NET_CAPABILITY_INTERNET).build();
            mConnectivityManager.requestNetwork(networkRequest, new NetworkCallback() {
                @Override
                public void onAvailable(Network network) {
                }
            });
        }));

        mPermissionTasks.put(CHANGE_WIFI_MULTICAST_STATE, new PermissionTest(false, () -> {
            WifiManager.MulticastLock multicastLock = mWifiManager.createMulticastLock(TAG);
            multicastLock.acquire();
            multicastLock.release();
        }));

        mPermissionTasks
                .put(CHANGE_WIFI_STATE,
                        new PermissionTest(false, () -> mWifiManager.setWifiEnabled(true)));

        mPermissionTasks.put(DISABLE_KEYGUARD, new PermissionTest(false, () -> {
            KeyguardManager.KeyguardLock keyguardLock = mKeyguardManager.newKeyguardLock(TAG);
            keyguardLock.disableKeyguard();
        }));

        mPermissionTasks.put(EXPAND_STATUS_BAR, new PermissionTest(false, () -> {
            Object statusBarManager = mContext.getSystemService("statusbar");
            invokeReflectionCall(statusBarManager.getClass(), "expandNotificationsPanel",
                    statusBarManager, null);
            // A short sleep is required to allow the notification panel to be expanded before
            // collapsing it to clean up after this test.
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                mLogger.logDebug("Caught an InterruptedException: ", e);
            }
            invokeReflectionCall(statusBarManager.getClass(), "collapsePanels",
                    statusBarManager, null);
        }));

        // andorid.permission.FLASHLIGHT has been removed.

        mPermissionTasks.put(FOREGROUND_SERVICE, new PermissionTest(true, () -> {
            // This test must run as a custom test because it requires a separate service be run in
            // in the foreground that can invoke startForeground.
            String permission = FOREGROUND_SERVICE;
            boolean permissionGranted = isPermissionGranted(permission);
            try {
                Intent serviceIntent = new Intent(mContext, TestService.class);
                serviceIntent.putExtra(EXTRA_PERMISSION_NAME, permission);
                serviceIntent.putExtra(EXTRA_PERMISSION_GRANTED, permissionGranted);
                mContext.startForegroundService(serviceIntent);
            } catch (Throwable t) {
                StatusLogger.logTestError(permission, t);
            }
        }));

        // android.permission.GET_PACKAGE_SIZE only guards PackageManager#getPackageSizeInfoAsUser
        // which is hidden and results in an UnsupportedOperationException after O.

        // android.permission.GET_TASKS has been deprecated and is no longer enforced.

        // android.permission.INSTALL_SHORTCUT is no longer used.

        mPermissionTasks.put(INTERNET, new PermissionTest(false, () -> {
            try {
                // Use a simple ServerSocket with a value of 0 to pick a free port to verify the
                // Internet permission.
                ServerSocket socket = new ServerSocket(0);
                socket.close();
            } catch (Throwable t) {
                // Sockets that require the Internet permission will not throw SecurityExceptions
                // but instead will throw SocketExceptions with a message containing EACCES
                // (Permission Denied).
                // NOTE: Later versions of the platform also return an EPERM error for this case.
                if (t instanceof SocketException && (t.getMessage().contains("EACCES")
                        || t.getMessage().contains("EPERM"))) {
                    throw new SecurityException(t);
                } else {
                    throw new UnexpectedPermissionTestFailureException(t);
                }
            }
        }));

        mPermissionTasks.put(KILL_BACKGROUND_PROCESSES, new PermissionTest(false,
                () -> mActivityManager.killBackgroundProcesses(Constants.COMPANION_PACKAGE)));

        // android.permission.MANAGE_ACCOUNTS has been removed.

        mPermissionTasks.put(MODIFY_AUDIO_SETTINGS, new PermissionTest(false, () -> {
            // This API does not throw a SecurityException but instead just logs a permission denial
            // similar to the following in logcat:
            // AS.AudioService: Audio Settings Permission Denial: setMicrophoneMute() from
            //     pid=26925, uid=10250
            boolean micMuted = mAudioManager.isMicrophoneMute();
            mAudioManager.setMicrophoneMute(!micMuted);
            if (mAudioManager.isMicrophoneMute() == micMuted) {
                throw new SecurityException("mic mute status could not be changed");
            }
            // restore the mic mute status to the original setting
            mAudioManager.setMicrophoneMute(micMuted);
        }));

        mPermissionTasks.put(MANAGE_OWN_CALLS, new PermissionTest(false, () -> {
            TelecomManager telecomManager = (TelecomManager) mContext.getSystemService(
                    Context.TELECOM_SERVICE);
            Uri numberUri = Uri.fromParts(PhoneAccount.SCHEME_TEL, "886", null);
            telecomManager.addNewIncomingCall(null, null);
            PhoneAccountHandle phoneAccountHandle = new PhoneAccountHandle(
                    new ComponentName(mContext, MainActivity.class), "TestId");
            telecomManager.isIncomingCallPermitted(phoneAccountHandle);
        }));

        mPermissionTasks.put(NFC, new PermissionTest(false, () -> {
            // SELinux blocks access to the NFC service from platform apps, so skip this test if the
            // app is platform signed.
            // SELinux : avc:  denied  { find } for service=nfc pid=24835 uid=10144
            //     scontext=u:r:platform_app:s0:c512,c768 tcontext=u:object_r:nfc_service:s0
            //     tclass=service_manager permissive=0
            // NFC     : could not retrieve NFC service
            NfcAdapter adapter = NfcAdapter.getDefaultAdapter(mContext);
            if (adapter == null) {
                throw new BypassTestException("An NFC adapter is not available to run this test");
            }
            adapter.setNdefPushMessage(null, mActivity);
            CardEmulation emulation = CardEmulation.getInstance(adapter);
            emulation.isDefaultServiceForCategory(new ComponentName(mContext, TestService.class),
                    CardEmulation.CATEGORY_PAYMENT);
        }));

        // android.permission.NFC_TRANSACTION_EVENT only guards broadcasts during NFC transactions.

        // android.permission.PERSISTENT_ACTIVITY is no longer used.

        // android.permission.READ_HISTORY_BOOKMARKS has been removed.

        // android.permission.READ_INSTALL_SESSIONS is no longer used.

        // android.permission.READ_PROFILE has been removed.

        // android.permission.READ_SOCIAL_STREAM has been removed.

        mPermissionTasks.put(READ_SYNC_SETTINGS,
                new PermissionTest(false, () -> ContentResolver.getMasterSyncAutomatically()));

        mPermissionTasks
                .put(READ_SYNC_STATS,
                        new PermissionTest(false, () -> ContentResolver.getCurrentSyncs()));

        // android.permission.READ_USER_DICTIONARY has been removed.

        // android.permission.RECEIVE_BOOT_COMPLETED only guards receiving the boot
        // completed broadcast.

        mPermissionTasks.put(REORDER_TASKS,
                new PermissionTest(false, () -> mActivityManager.moveTaskToFront(2, 0)));

        // android.permission.REQUEST_COMKPANION_RUN_IN_BACKGROUND requires companion device
        // with which to associate this app.

        // android.permission.REQUEST_COMPANION_USE_DATA_IN_BACKGROUND requires companion device
        // with which to associate this app.

        mPermissionTasks.put(REQUEST_DELETE_PACKAGES, new PermissionTest(false, () -> {
            Intent intent = new Intent(mActivity, TestActivity.class);
            PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, intent, 0);
            // Use a version of this package that does not exist on the device to make this a
            // noop after the permission check.
            VersionedPackage versionedPackage = new VersionedPackage(mPackageName, 0);
            mPackageInstaller.uninstall(versionedPackage, pendingIntent.getIntentSender());
        }));

        // android.permission.RESTART_PACKAGES only guarded ActivityManager#restartPackages which
        // is no longer supported.

        mPermissionTasks
                .put(SET_WALLPAPER,
                        new PermissionTest(false, () -> mWallpaperManager.clearWallpaper()));

        mPermissionTasks.put(SET_WALLPAPER_HINTS, new PermissionTest(false, () -> {
            Rect rect = new Rect(0, 0, 1, 1);
            mWallpaperManager.setDisplayPadding(rect);
        }));

        // android.permission.SUBSCRIBED_FEEDS_READ has been removed.

        // android.permission.SUBSCRIBED_FEEDS_WRITE has been removed.

        mPermissionTasks.put(TRANSMIT_IR, new PermissionTest(false, () -> {
            try {
                mConsumerIrManager.getCarrierFrequencies();
            } catch (UnsupportedOperationException e) {
                // This Exception indicates the app has been granted the required permission to
                // invoke this API but the device does not have the IR feature.
            }
        }));

        // android.permission.UNINSTALL_SHORTCUT is no longer used.

        mPermissionTasks.put(USE_BIOMETRIC, new PermissionTest(false, () -> {
            if (mDeviceApiLevel == Build.VERSION_CODES.P) {
                FingerprintManager fingerprintManager =
                        (FingerprintManager) mContext.getSystemService(
                                Context.FINGERPRINT_SERVICE);
                if (fingerprintManager == null) {
                    throw new BypassTestException(
                            "The FingerprintManager is not available on this device");
                }
                fingerprintManager.isHardwareDetected();
            } else {
                // The BiometricManager was introduced in Android 10 and is more appropriate to use
                // for this permission. Android 10 introduced the canAuthenticate method while
                // Android 11 deprecated that in favor of an overloaded version that accepts
                // an int representing Authenticators.
                BiometricManager biometricManager = (BiometricManager) mContext.getSystemService(
                        Context.BIOMETRIC_SERVICE);
                if (mDeviceApiLevel == Build.VERSION_CODES.Q) {
                    biometricManager.canAuthenticate();
                } else {
                    biometricManager.canAuthenticate(
                            BiometricManager.Authenticators.BIOMETRIC_STRONG);
                }
            }
        }));

        // android.permission.USE_CREDENTIALS has been removed.

        mPermissionTasks.put(USE_FINGERPRINT,
                new PermissionTest(false, () -> {
                    FingerprintManager fingerprintManager =
                            (FingerprintManager) mContext.getSystemService(
                                    Context.FINGERPRINT_SERVICE);
                    if (fingerprintManager == null) {
                        throw new BypassTestException(
                                "The FingerprintManager is not available on this device");
                    }
                    fingerprintManager.hasEnrolledFingerprints();
                }));

        mPermissionTasks.put(VIBRATE, new PermissionTest(false, () -> mVibrator
                .vibrate(VibrationEffect.createOneShot(100, VibrationEffect.DEFAULT_AMPLITUDE))));

        mPermissionTasks.put(WAKE_LOCK, new PermissionTest(false, () -> {
            PowerManager.WakeLock wakeLock = mPowerManager.newWakeLock(
                    PowerManager.PARTIAL_WAKE_LOCK,
                    InstallPermissionTester.class.getSimpleName() + "::" + TAG);
            wakeLock.acquire();
            wakeLock.release();
        }));

        // android.permission.WRITE_HISTORY_BOOKMARKS has been removed.

        // android.permission.WRITE_PROFILE has been removed.

        // android.permission.WRITE_SMS has been removed.

        // android.permission.WRITE_SOCIAL_STREAM has been removed.

        mPermissionTasks.put(WRITE_SYNC_SETTINGS,
                new PermissionTest(false, () -> ContentResolver.setMasterSyncAutomatically(true)));

        // android.permission.WRITE_USER_DICTIONARY has been removed.

        // new install permissions for Q
        mPermissionTasks.put(REQUEST_PASSWORD_COMPLEXITY,
                new PermissionTest(false, Build.VERSION_CODES.Q,
                        () -> mDevicePolicyManager.getPasswordComplexity()));

        mPermissionTasks.put(USE_FULL_SCREEN_INTENT,
                new PermissionTest(false, Build.VERSION_CODES.Q, () -> {
                    Intent notificationIntent = new Intent(mContext, MainActivity.class);
                    PendingIntent pendingIntent =
                            PendingIntent.getActivity(mContext, 0, notificationIntent, 0);

                    Resources resources = mContext.getResources();
                    CharSequence channelName = resources.getString(R.string.tester_channel_name);
                    NotificationChannel channel = new NotificationChannel(TAG, channelName,
                            NotificationManager.IMPORTANCE_DEFAULT);
                    NotificationManager notificationManager = mContext.getSystemService(
                            NotificationManager.class);
                    notificationManager.createNotificationChannel(channel);

                    Notification notification =
                            new Notification.Builder(mContext, TAG)
                                    .setContentTitle(resources.getText(
                                            R.string.full_screen_intent_notification_title))
                                    .setContentText(resources.getText(
                                            R.string.full_screen_intent_notification_message))
                                    .setSmallIcon(R.drawable.ic_launcher_foreground)
                                    .setContentIntent(pendingIntent)
                                    .setFullScreenIntent(pendingIntent, false)
                                    .build();
                    notificationManager.notify(0, notification);
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        mLogger.logError("Caught an InterruptedException: " + e);
                    }
                    StatusBarNotification[] notifications =
                            notificationManager.getActiveNotifications();
                    if (notifications.length == 0) {
                        throw new SecurityException(
                                "fullScreenIntent not displayed as an active notification");
                    }
                    for (StatusBarNotification statusBarNotification : notifications) {
                        if (statusBarNotification.getNotification().fullScreenIntent == null) {
                            throw new SecurityException(
                                    "fullScreenIntent field cleared after launching notification");
                        }
                    }
                }));

        // new install permissions for R
        mPermissionTasks.put(NFC_PREFERRED_PAYMENT_INFO,
                new PermissionTest(false, Build.VERSION_CODES.R, () -> {
                    NfcAdapter adapter = NfcAdapter.getDefaultAdapter(mContext);
                    if (adapter == null) {
                        throw new BypassTestException(
                                "An NFC adapter is not available to run this test");
                    }
                    CardEmulation cardEmulation = CardEmulation.getInstance(adapter);
                    cardEmulation.getDescriptionForPreferredPaymentService();
                }));

        mPermissionTasks.put(QUERY_ALL_PACKAGES,
                new PermissionTest(false, Build.VERSION_CODES.R, () -> {
                    try {
                        // The companion package should be installed to act as a queryable package
                        // for this test; without a <queries> tag in the AndroidManifest and without
                        // this permission granted a query for the companion package should result
                        // in a NameNotFoundException.
                        PackageInfo packageInfo = mPackageManager.getPackageInfo(
                                Constants.COMPANION_PACKAGE, 0);
                    } catch (PackageManager.NameNotFoundException e) {
                        throw new SecurityException(e);
                    }
                }));
    }