Search in sources :

Example 1 with SsaidSettings

use of io.github.muntashirakon.AppManager.ssaid.SsaidSettings in project AppManager by MuntashirAkon.

the class BackupOp method backupExtras.

private void backupExtras() throws BackupException {
    PseudoRules rules = new PseudoRules(mPackageName, mUserId);
    Path miscFile;
    try {
        miscFile = mBackupFile.getMiscFile(CryptoUtils.MODE_NO_ENCRYPTION);
    } catch (IOException e) {
        throw new BackupException("Couldn't get misc.am.tsv", e);
    }
    // Backup permissions
    @NonNull String[] permissions = ArrayUtils.defeatNullable(mPackageInfo.requestedPermissions);
    int[] permissionFlags = mPackageInfo.requestedPermissionsFlags;
    List<OpEntry> opEntries = new ArrayList<>();
    try {
        List<PackageOps> packageOpsList = new AppOpsService().getOpsForPackage(mPackageInfo.applicationInfo.uid, mPackageName, null);
        if (packageOpsList.size() == 1)
            opEntries.addAll(packageOpsList.get(0).getOps());
    } catch (Exception ignore) {
    }
    PermissionInfo info;
    int basePermissionType;
    int protectionLevels;
    for (int i = 0; i < permissions.length; ++i) {
        try {
            info = mPm.getPermissionInfo(permissions[i], 0);
            basePermissionType = PermissionInfoCompat.getProtection(info);
            protectionLevels = PermissionInfoCompat.getProtectionFlags(info);
            if (basePermissionType != PermissionInfo.PROTECTION_DANGEROUS && (protectionLevels & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) == 0) {
                // Don't include permissions that are neither dangerous nor development
                continue;
            }
            boolean isGranted = (permissionFlags[i] & PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0;
            int permFlags = PermissionCompat.getPermissionFlags(info.name, mPackageName, mUserId);
            rules.setPermission(permissions[i], isGranted, permFlags);
        } catch (PackageManager.NameNotFoundException | RemoteException ignore) {
        }
    }
    // Backup app ops
    for (OpEntry entry : opEntries) {
        rules.setAppOp(entry.getOp(), entry.getMode());
    }
    // Backup MagiskHide data
    Collection<String> magiskHiddenProcesses = MagiskHide.getProcesses(mPackageName);
    for (String processName : magiskHiddenProcesses) {
        rules.setMagiskHide(processName, true);
    }
    // Backup Magisk DenyList data
    Collection<String> magiskDeniedProcesses = MagiskDenyList.getProcesses(mPackageName);
    for (String processName : magiskDeniedProcesses) {
        rules.setMagiskDenyList(processName, true);
    }
    // Backup allowed notification listeners aka BIND_NOTIFICATION_LISTENER_SERVICE
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
        INotificationManager notificationManager = INotificationManager.Stub.asInterface(ProxyBinder.getService(Context.NOTIFICATION_SERVICE));
        try {
            List<ComponentName> notificationComponents;
            if (LocalServer.isAMServiceAlive()) {
                notificationComponents = notificationManager.getEnabledNotificationListeners(mUserId);
            } else
                notificationComponents = Collections.emptyList();
            List<String> componentsForThisPkg = new ArrayList<>();
            for (ComponentName componentName : notificationComponents) {
                if (mPackageName.equals(componentName.getPackageName())) {
                    componentsForThisPkg.add(componentName.getClassName());
                }
            }
            for (String component : componentsForThisPkg) {
                rules.setNotificationListener(component, true);
            }
        } catch (RemoteException ignore) {
        }
    }
    // Backup battery optimization
    String targetString = "user," + mPackageName + "," + mApplicationInfo.uid;
    Runner.Result result = Runner.runCommand(new String[] { "dumpsys", "deviceidle", "whitelist" });
    if (result.isSuccessful() && result.getOutput().contains(targetString)) {
        rules.setBatteryOptimization(false);
    }
    // Backup net policy
    int policies = NetworkPolicyManagerCompat.getUidPolicy(mApplicationInfo.uid);
    if (policies > 0) {
        // Store only if there is a policy
        rules.setNetPolicy(policies);
    }
    // Backup URI grants
    List<UriManager.UriGrant> uriGrants = new UriManager().getGrantedUris(mPackageName);
    if (uriGrants != null) {
        for (UriManager.UriGrant uriGrant : uriGrants) {
            if (uriGrant.targetUserId == mUserId) {
                rules.setUriGrant(uriGrant);
            }
        }
    }
    // Backup SSAID
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        try {
            String ssaid = new SsaidSettings(mPackageName, mApplicationInfo.uid).getSsaid();
            if (ssaid != null)
                rules.setSsaid(ssaid);
        } catch (IOException e) {
            // Ignore exception
            Log.e(TAG, e);
        }
    }
    rules.commitExternal(miscFile);
    if (!miscFile.exists())
        return;
    try {
        encrypt(new Path[] { miscFile });
        // Overwrite with the new file
        miscFile = mBackupFile.getMiscFile(mMetadata.crypto);
        // Store checksum
        mChecksum.add(miscFile.getName(), DigestUtils.getHexDigest(mMetadata.checksumAlgo, miscFile));
    } catch (IOException e) {
        throw new BackupException("Couldn't get misc.am.tsv for generating checksum", e);
    }
}
Also used : Runner(io.github.muntashirakon.AppManager.runner.Runner) ArrayList(java.util.ArrayList) PseudoRules(io.github.muntashirakon.AppManager.rules.PseudoRules) AppOpsService(io.github.muntashirakon.AppManager.appops.AppOpsService) INotificationManager(android.app.INotificationManager) NonNull(androidx.annotation.NonNull) SsaidSettings(io.github.muntashirakon.AppManager.ssaid.SsaidSettings) OpEntry(io.github.muntashirakon.AppManager.appops.OpEntry) ComponentName(android.content.ComponentName) Path(io.github.muntashirakon.io.Path) IOException(java.io.IOException) CryptoException(io.github.muntashirakon.AppManager.crypto.CryptoException) FileNotFoundException(java.io.FileNotFoundException) RemoteException(android.os.RemoteException) IOException(java.io.IOException) PermissionInfo(android.content.pm.PermissionInfo) UriManager(io.github.muntashirakon.AppManager.uri.UriManager) RemoteException(android.os.RemoteException) PackageOps(io.github.muntashirakon.AppManager.appops.PackageOps)

Example 2 with SsaidSettings

use of io.github.muntashirakon.AppManager.ssaid.SsaidSettings in project AppManager by MuntashirAkon.

the class RestoreOp method restoreExtras.

private synchronized void restoreExtras() throws BackupException {
    if (!isInstalled) {
        throw new BackupException("Misc restore is requested but the app isn't installed.");
    }
    PseudoRules rules = new PseudoRules(packageName, userHandle);
    // Backward compatibility for restoring permissions
    loadMiscRules(rules);
    // Apply rules
    List<RuleEntry> entries = rules.getAll();
    AppOpsService appOpsService = new AppOpsService();
    INotificationManager notificationManager = INotificationManager.Stub.asInterface(ProxyBinder.getService(Context.NOTIFICATION_SERVICE));
    boolean magiskHideAvailable = MagiskHide.available();
    for (RuleEntry entry : entries) {
        try {
            switch(entry.type) {
                case APP_OP:
                    appOpsService.setMode(Integer.parseInt(entry.name), packageInfo.applicationInfo.uid, packageName, ((AppOpRule) entry).getMode());
                    break;
                case NET_POLICY:
                    NetworkPolicyManagerCompat.setUidPolicy(packageInfo.applicationInfo.uid, ((NetPolicyRule) entry).getPolicies());
                    break;
                case PERMISSION:
                    {
                        PermissionRule permissionRule = (PermissionRule) entry;
                        Permission permission = permissionRule.getPermission(true);
                        permission.setAppOpAllowed(permission.getAppOp() != OP_NONE && appOpsService.checkOperation(permission.getAppOp(), packageInfo.applicationInfo.uid, packageName) == AppOpsManager.MODE_ALLOWED);
                        if (permissionRule.isGranted()) {
                            PermUtils.grantPermission(packageInfo, permission, appOpsService, true, true);
                        } else {
                            PermUtils.revokePermission(packageInfo, permission, appOpsService, true);
                        }
                        break;
                    }
                case BATTERY_OPT:
                    Runner.runCommand(new String[] { "dumpsys", "deviceidle", "whitelist", "+" + packageName });
                    break;
                case MAGISK_HIDE:
                    {
                        MagiskHideRule magiskHideRule = (MagiskHideRule) entry;
                        if (magiskHideAvailable) {
                            if (magiskHideRule.isHidden()) {
                                MagiskHide.add(packageName, magiskHideRule.getProcessName());
                            } else {
                                MagiskHide.remove(packageName, magiskHideRule.getProcessName());
                            }
                        } else {
                            // Fall-back to Magisk DenyList
                            if (magiskHideRule.isHidden()) {
                                MagiskDenyList.add(packageName, magiskHideRule.getProcessName());
                            } else {
                                MagiskDenyList.remove(packageName, magiskHideRule.getProcessName());
                            }
                        }
                        break;
                    }
                case MAGISK_DENY_LIST:
                    {
                        MagiskDenyListRule magiskDenyListRule = (MagiskDenyListRule) entry;
                        if (magiskDenyListRule.isDenied()) {
                            MagiskDenyList.add(packageName, magiskDenyListRule.getProcessName());
                        } else {
                            MagiskDenyList.remove(packageName, magiskDenyListRule.getProcessName());
                        }
                        break;
                    }
                case NOTIFICATION:
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
                        notificationManager.setNotificationListenerAccessGrantedForUser(new ComponentName(packageName, entry.name), userHandle, true);
                    }
                    break;
                case URI_GRANT:
                    UriManager.UriGrant uriGrant = ((UriGrantRule) entry).getUriGrant();
                    UriManager.UriGrant newUriGrant = new UriManager.UriGrant(uriGrant.sourceUserId, userHandle, uriGrant.userHandle, uriGrant.sourcePkg, uriGrant.targetPkg, uriGrant.uri, uriGrant.prefix, uriGrant.modeFlags, uriGrant.createdTime);
                    UriManager uriManager = new UriManager();
                    uriManager.grantUri(newUriGrant);
                    uriManager.writeGrantedUriPermissions();
                    break;
                case SSAID:
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                        new SsaidSettings(packageName, packageInfo.applicationInfo.uid).setSsaid(((SsaidRule) entry).getSsaid());
                    }
                    break;
            }
        } catch (Throwable e) {
            // There are several reason restoring these things go wrong, especially when
            // downgrading from an Android to another. It's better to simply suppress these
            // exceptions instead of causing a failure or worse, a crash
            Log.e(TAG, e);
        }
    }
}
Also used : UriGrantRule(io.github.muntashirakon.AppManager.rules.struct.UriGrantRule) PermissionRule(io.github.muntashirakon.AppManager.rules.struct.PermissionRule) MagiskDenyListRule(io.github.muntashirakon.AppManager.rules.struct.MagiskDenyListRule) PseudoRules(io.github.muntashirakon.AppManager.rules.PseudoRules) AppOpsService(io.github.muntashirakon.AppManager.appops.AppOpsService) MagiskHideRule(io.github.muntashirakon.AppManager.rules.struct.MagiskHideRule) INotificationManager(android.app.INotificationManager) SsaidSettings(io.github.muntashirakon.AppManager.ssaid.SsaidSettings) Permission(io.github.muntashirakon.AppManager.permission.Permission) UriManager(io.github.muntashirakon.AppManager.uri.UriManager) RuleEntry(io.github.muntashirakon.AppManager.rules.struct.RuleEntry) ComponentName(android.content.ComponentName)

Example 3 with SsaidSettings

use of io.github.muntashirakon.AppManager.ssaid.SsaidSettings in project AppManager by MuntashirAkon.

the class AppInfoFragment method setupTagCloud.

@UiThread
private void setupTagCloud(AppInfoViewModel.TagCloud tagCloud) {
    mTagCloud.removeAllViews();
    if (mainModel == null)
        return;
    // Add tracker chip
    if (!tagCloud.trackerComponents.isEmpty()) {
        CharSequence[] trackerComponentNames = new CharSequence[tagCloud.trackerComponents.size()];
        for (int i = 0; i < trackerComponentNames.length; ++i) {
            ComponentRule rule = tagCloud.trackerComponents.get(i);
            trackerComponentNames[i] = rule.isBlocked() ? getColoredText(rule.name, ContextCompat.getColor(mActivity, R.color.stopped)) : rule.name;
        }
        addChip(getResources().getQuantityString(R.plurals.no_of_trackers, tagCloud.trackerComponents.size(), tagCloud.trackerComponents.size()), tagCloud.areAllTrackersBlocked ? R.color.stopped : R.color.tracker).setOnClickListener(v -> {
            if (!isExternalApk && isRootEnabled) {
                new SearchableMultiChoiceDialogBuilder<>(mActivity, tagCloud.trackerComponents, trackerComponentNames).setTitle(R.string.trackers).setSelections(tagCloud.trackerComponents).setNegativeButton(R.string.cancel, null).setPositiveButton(R.string.block, (dialog, which, selectedItems) -> {
                    showProgressIndicator(true);
                    executor.submit(() -> {
                        mainModel.addRules(selectedItems, true);
                        runOnUiThread(() -> {
                            if (isDetached())
                                return;
                            showProgressIndicator(false);
                            displayShortToast(R.string.done);
                        });
                    });
                }).setNeutralButton(R.string.unblock, (dialog, which, selectedItems) -> {
                    showProgressIndicator(true);
                    executor.submit(() -> {
                        mainModel.removeRules(selectedItems, true);
                        runOnUiThread(() -> {
                            if (isDetached())
                                return;
                            showProgressIndicator(false);
                            displayShortToast(R.string.done);
                        });
                    });
                }).show();
            } else {
                new MaterialAlertDialogBuilder(mActivity).setTitle(R.string.trackers).setItems(trackerComponentNames, null).setNegativeButton(R.string.close, null).show();
            }
        });
    }
    if (tagCloud.isSystemApp) {
        if (tagCloud.isSystemlessPath) {
            addChip(R.string.systemless_app);
        } else
            addChip(R.string.system_app);
        if (tagCloud.isUpdatedSystemApp) {
            addChip(R.string.updated_app);
        }
    } else if (!mainModel.getIsExternalApk())
        addChip(R.string.user_app);
    if (tagCloud.splitCount > 0) {
        addChip(getResources().getQuantityString(R.plurals.no_of_splits, tagCloud.splitCount, tagCloud.splitCount)).setOnClickListener(v -> {
            try (ApkFile apkFile = ApkFile.getInstance(mainModel.getApkFileKey())) {
                // Display a list of apks
                List<ApkFile.Entry> apkEntries = apkFile.getEntries();
                CharSequence[] entryNames = new CharSequence[tagCloud.splitCount];
                for (int i = 0; i < tagCloud.splitCount; ++i) {
                    entryNames[i] = apkEntries.get(i + 1).toLocalizedString(mActivity);
                }
                new MaterialAlertDialogBuilder(mActivity).setTitle(R.string.splits).setItems(entryNames, null).setNegativeButton(R.string.close, null).show();
            }
        });
    }
    if (tagCloud.isDebuggable) {
        addChip(R.string.debuggable);
    }
    if (tagCloud.isTestOnly) {
        addChip(R.string.test_only);
    }
    if (!tagCloud.hasCode) {
        addChip(R.string.no_code);
    }
    if (tagCloud.hasRequestedLargeHeap) {
        addChip(R.string.requested_large_heap, R.color.tracker);
    }
    if (tagCloud.runningServices.size() > 0) {
        addChip(R.string.running, R.color.running).setOnClickListener(v -> {
            mProgressIndicator.show();
            executor.submit(() -> {
                CharSequence[] runningServices = new CharSequence[tagCloud.runningServices.size()];
                for (int i = 0; i < runningServices.length; ++i) {
                    runningServices[i] = new SpannableStringBuilder().append(getTitleText(mActivity, tagCloud.runningServices.get(i).service.getShortClassName())).append("\n").append(getSmallerText(new SpannableStringBuilder().append(getStyledKeyValue(mActivity, R.string.process_name, tagCloud.runningServices.get(i).process)).append("\n").append(getStyledKeyValue(mActivity, R.string.pid, String.valueOf(tagCloud.runningServices.get(i).pid)))));
                }
                DialogTitleBuilder titleBuilder = new DialogTitleBuilder(mActivity).setTitle(R.string.running_services);
                if (PermissionUtils.hasDumpPermission() && FeatureController.isLogViewerEnabled()) {
                    titleBuilder.setSubtitle(R.string.running_services_logcat_hint);
                }
                runOnUiThread(() -> {
                    mProgressIndicator.hide();
                    MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(mActivity).setCustomTitle(titleBuilder.build()).setItems(runningServices, (dialog, which) -> {
                        if (!FeatureController.isLogViewerEnabled())
                            return;
                        Intent logViewerIntent = new Intent(mActivity.getApplicationContext(), LogViewerActivity.class).setAction(LogViewerActivity.ACTION_LAUNCH).putExtra(LogViewerActivity.EXTRA_FILTER, SearchCriteria.PID_KEYWORD + tagCloud.runningServices.get(which).pid).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        mActivity.startActivity(logViewerIntent);
                    }).setNeutralButton(R.string.force_stop, (dialog, which) -> executor.submit(() -> {
                        try {
                            PackageManagerCompat.forceStopPackage(mPackageName, mainModel.getUserHandle());
                            runOnUiThread(this::refreshDetails);
                        } catch (RemoteException | SecurityException e) {
                            Log.e(TAG, e);
                            displayLongToast(R.string.failed_to_stop, mPackageLabel);
                        }
                    })).setNegativeButton(R.string.close, null);
                    builder.show();
                });
            });
        });
    }
    if (tagCloud.isForceStopped) {
        addChip(R.string.stopped, R.color.stopped);
    }
    if (!tagCloud.isAppEnabled) {
        addChip(R.string.disabled_app, R.color.disabled_user);
    }
    if (tagCloud.isAppSuspended) {
        addChip(R.string.suspended, R.color.stopped);
    }
    if (tagCloud.isAppHidden) {
        addChip(R.string.hidden, R.color.disabled_user);
    }
    magiskHiddenProcesses = tagCloud.magiskHiddenProcesses;
    if (tagCloud.isMagiskHideEnabled) {
        addChip(R.string.magisk_hide_enabled).setOnClickListener(v -> displayMagiskHideDialog());
    }
    magiskDeniedProcesses = tagCloud.magiskDeniedProcesses;
    if (tagCloud.isMagiskDenyListEnabled) {
        addChip(R.string.magisk_denylist).setOnClickListener(v -> displayMagiskDenyListDialog());
    }
    if (tagCloud.hasKeyStoreItems) {
        Chip chip;
        if (tagCloud.hasMasterKeyInKeyStore) {
            chip = addChip(R.string.keystore, R.color.tracker);
        } else
            chip = addChip(R.string.keystore);
        chip.setOnClickListener(view -> new MaterialAlertDialogBuilder(mActivity).setTitle(R.string.keystore).setItems(KeyStoreUtils.getKeyStoreFiles(mApplicationInfo.uid, mainModel.getUserHandle()).toArray(new String[0]), null).setNegativeButton(R.string.close, null).show());
    }
    if (tagCloud.backups.length > 0) {
        CharSequence[] backupNames = new CharSequence[tagCloud.backups.length];
        for (int i = 0; i < tagCloud.backups.length; ++i) {
            backupNames[i] = tagCloud.backups[i].toLocalizedString(mActivity);
        }
        addChip(R.string.backup).setOnClickListener(v -> new MaterialAlertDialogBuilder(mActivity).setTitle(R.string.backup).setItems(backupNames, null).setNegativeButton(R.string.close, null).show());
    }
    if (!tagCloud.isBatteryOptimized) {
        addChip(R.string.no_battery_optimization, R.color.red_orange).setOnClickListener(v -> new MaterialAlertDialogBuilder(mActivity).setTitle(R.string.battery_optimization).setMessage(R.string.enable_battery_optimization).setNegativeButton(R.string.no, null).setPositiveButton(R.string.yes, (dialog, which) -> {
            Runner.runCommand(new String[] { "dumpsys", "deviceidle", "whitelist", "-" + mPackageName });
            refreshDetails();
        }).show());
    }
    if (tagCloud.netPolicies > 0) {
        String[] readablePolicies = NetworkPolicyManagerCompat.getReadablePolicies(mActivity, tagCloud.netPolicies).values().toArray(new String[0]);
        addChip(R.string.has_net_policy).setOnClickListener(v -> new MaterialAlertDialogBuilder(mActivity).setTitle(R.string.net_policy).setItems(readablePolicies, null).setNegativeButton(R.string.ok, null).show());
    }
    if (tagCloud.ssaid != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        addChip(R.string.ssaid, R.color.red_orange).setOnClickListener(v -> {
            View view = getLayoutInflater().inflate(R.layout.dialog_ssaid_info, null);
            AlertDialog alertDialog = new MaterialAlertDialogBuilder(mActivity).setTitle(R.string.ssaid).setView(view).setPositiveButton(R.string.apply, null).setNegativeButton(R.string.close, null).setNeutralButton(R.string.reset_to_default, null).create();
            TextInputEditText ssaidHolder = view.findViewById(R.id.ssaid);
            TextInputLayout ssaidInputLayout = view.findViewById(android.R.id.text1);
            AtomicReference<Button> applyButton = new AtomicReference<>();
            AtomicReference<Button> resetButton = new AtomicReference<>();
            AtomicReference<String> ssaid = new AtomicReference<>(tagCloud.ssaid);
            alertDialog.setOnShowListener(dialog -> {
                applyButton.set(alertDialog.getButton(AlertDialog.BUTTON_POSITIVE));
                resetButton.set(alertDialog.getButton(AlertDialog.BUTTON_NEUTRAL));
                applyButton.get().setVisibility(View.GONE);
                applyButton.get().setOnClickListener(v2 -> executor.submit(() -> {
                    try {
                        SsaidSettings ssaidSettings = new SsaidSettings(mPackageName, mApplicationInfo.uid);
                        if (ssaidSettings.setSsaid(ssaid.get())) {
                            model.loadTagCloud();
                            runOnUiThread(() -> displayLongToast(R.string.restart_to_reflect_changes));
                        } else {
                            runOnUiThread(() -> displayLongToast(R.string.failed_to_change_ssaid));
                        }
                        alertDialog.dismiss();
                    } catch (IOException ignore) {
                    }
                }));
                resetButton.get().setVisibility(View.GONE);
                resetButton.get().setOnClickListener(v2 -> {
                    ssaid.set(tagCloud.ssaid);
                    ssaidHolder.setText(ssaid.get());
                    resetButton.get().setVisibility(View.GONE);
                    applyButton.get().setVisibility(View.GONE);
                });
            });
            ssaidHolder.setText(tagCloud.ssaid);
            ssaidHolder.setTypeface(Typeface.MONOSPACE);
            ssaidHolder.setOnClickListener(v2 -> {
                ClipboardManager clipboard = (ClipboardManager) mActivity.getSystemService(Context.CLIPBOARD_SERVICE);
                ClipData clip = ClipData.newPlainText("SSAID", ssaid.get());
                clipboard.setPrimaryClip(clip);
                displayShortToast(R.string.copied_to_clipboard);
            });
            ssaidInputLayout.setEndIconOnClickListener(v2 -> {
                ssaid.set(SsaidSettings.generateSsaid(mPackageName));
                ssaidHolder.setText(ssaid.get());
                if (!tagCloud.ssaid.equals(ssaid.get())) {
                    if (resetButton.get() != null) {
                        resetButton.get().setVisibility(View.VISIBLE);
                    }
                    if (applyButton.get() != null) {
                        applyButton.get().setVisibility(View.VISIBLE);
                    }
                }
            });
            alertDialog.show();
        });
    }
    if (tagCloud.uriGrants != null) {
        addChip(R.string.saf).setOnClickListener(v -> {
            CharSequence[] uriGrants = new CharSequence[tagCloud.uriGrants.size()];
            for (int i = 0; i < tagCloud.uriGrants.size(); ++i) {
                uriGrants[i] = tagCloud.uriGrants.get(i).uri.toString();
            }
            new MaterialAlertDialogBuilder(mActivity).setTitle(R.string.saf).setItems(uriGrants, null).setNegativeButton(R.string.close, null).show();
        });
    }
    if (tagCloud.usesPlayAppSigning) {
        addChip(R.string.uses_play_app_signing, R.color.disabled_user).setOnClickListener(v -> new MaterialAlertDialogBuilder(mActivity).setTitle(R.string.uses_play_app_signing).setMessage(R.string.uses_play_app_signing_description).setNegativeButton(R.string.close, null).show());
    }
}
Also used : Chip(com.google.android.material.chip.Chip) Arrays(java.util.Arrays) Bundle(android.os.Bundle) NonNull(androidx.annotation.NonNull) BackupDialogFragment(io.github.muntashirakon.AppManager.backup.BackupDialogFragment) BuildConfig(io.github.muntashirakon.AppManager.BuildConfig) ComponentRule(io.github.muntashirakon.AppManager.rules.struct.ComponentRule) ProxyFile(io.github.muntashirakon.io.ProxyFile) Uri(android.net.Uri) ImageView(android.widget.ImageView) Drawable(android.graphics.drawable.Drawable) LogViewerActivity(io.github.muntashirakon.AppManager.logcat.LogViewerActivity) Manifest(android.Manifest) UIUtils.getStyledKeyValue(io.github.muntashirakon.AppManager.utils.UIUtils.getStyledKeyValue) NoRootAccessibilityService(io.github.muntashirakon.AppManager.accessibility.NoRootAccessibilityService) UIUtils.displayLongToast(io.github.muntashirakon.AppManager.utils.UIUtils.displayLongToast) UIUtils.displayShortToast(io.github.muntashirakon.AppManager.utils.UIUtils.displayShortToast) Fragment(androidx.fragment.app.Fragment) ClipboardManager(android.content.ClipboardManager) UiThread(androidx.annotation.UiThread) ContextCompat(androidx.core.content.ContextCompat) R(io.github.muntashirakon.AppManager.R) ArrayMap(androidx.collection.ArrayMap) Runner(io.github.muntashirakon.AppManager.runner.Runner) PackageManagerCompat(io.github.muntashirakon.AppManager.servermanager.PackageManagerCompat) LinearProgressIndicator(com.google.android.material.progressindicator.LinearProgressIndicator) NetworkPolicyManager(android.net.NetworkPolicyManager) KeyStoreUtils(io.github.muntashirakon.AppManager.utils.KeyStoreUtils) FileUtils(io.github.muntashirakon.AppManager.utils.FileUtils) UIUtils(io.github.muntashirakon.AppManager.utils.UIUtils) Executors(java.util.concurrent.Executors) StringRes(androidx.annotation.StringRes) Nullable(androidx.annotation.Nullable) SearchableMultiChoiceDialogBuilder(io.github.muntashirakon.AppManager.types.SearchableMultiChoiceDialogBuilder) LangUtils(io.github.muntashirakon.AppManager.utils.LangUtils) UIUtils.getColoredText(io.github.muntashirakon.AppManager.utils.UIUtils.getColoredText) ActivityResultContracts(androidx.activity.result.contract.ActivityResultContracts) MagiskHide(io.github.muntashirakon.AppManager.magisk.MagiskHide) LinearLayoutManager(androidx.recyclerview.widget.LinearLayoutManager) UiThreadHandler(io.github.muntashirakon.AppManager.utils.UiThreadHandler) PackageInstallerActivity(io.github.muntashirakon.AppManager.apk.installer.PackageInstallerActivity) RunnerUtils(io.github.muntashirakon.AppManager.runner.RunnerUtils) ServiceHelper(io.github.muntashirakon.AppManager.logcat.helper.ServiceHelper) SsaidSettings(io.github.muntashirakon.AppManager.ssaid.SsaidSettings) TextInputLayout(com.google.android.material.textfield.TextInputLayout) PackageSizeInfo(io.github.muntashirakon.AppManager.types.PackageSizeInfo) HIDDEN_API_ENFORCEMENT_DISABLED(io.github.muntashirakon.AppManager.servermanager.ApplicationInfoCompat.HIDDEN_API_ENFORCEMENT_DISABLED) WorkerThread(androidx.annotation.WorkerThread) RemoteException(android.os.RemoteException) ArrayList(java.util.ArrayList) PermissionUtils(io.github.muntashirakon.AppManager.utils.PermissionUtils) SpannableStringBuilder(android.text.SpannableStringBuilder) Path(io.github.muntashirakon.io.Path) UIUtils.getSecondaryText(io.github.muntashirakon.AppManager.utils.UIUtils.getSecondaryText) MenuInflater(android.view.MenuInflater) Menu(android.view.Menu) Settings(android.provider.Settings) SearchCriteria(io.github.muntashirakon.AppManager.logcat.struct.SearchCriteria) DateUtils(io.github.muntashirakon.AppManager.utils.DateUtils) Formatter(android.text.format.Formatter) NetworkPolicyManagerCompat(io.github.muntashirakon.AppManager.servermanager.NetworkPolicyManagerCompat) ViewModelProvider(androidx.lifecycle.ViewModelProvider) ComponentName(android.content.ComponentName) PackageInfoCompat(androidx.core.content.pm.PackageInfoCompat) IOException(java.io.IOException) AnyThread(androidx.annotation.AnyThread) WhatsNewDialogFragment(io.github.muntashirakon.AppManager.apk.whatsnew.WhatsNewDialogFragment) HIDDEN_API_ENFORCEMENT_JUST_WARN(io.github.muntashirakon.AppManager.servermanager.ApplicationInfoCompat.HIDDEN_API_ENFORCEMENT_JUST_WARN) Utils(io.github.muntashirakon.AppManager.utils.Utils) File(java.io.File) AccessibilityMultiplexer(io.github.muntashirakon.AppManager.accessibility.AccessibilityMultiplexer) FastScrollerBuilder(me.zhanghai.android.fastscroll.FastScrollerBuilder) UIUtils.getSmallerText(io.github.muntashirakon.AppManager.utils.UIUtils.getSmallerText) DigestUtils(io.github.muntashirakon.AppManager.utils.DigestUtils) AppDetailsActivity(io.github.muntashirakon.AppManager.details.AppDetailsActivity) IntentUtils(io.github.muntashirakon.AppManager.utils.IntentUtils) ComponentsBlocker(io.github.muntashirakon.AppManager.rules.compontents.ComponentsBlocker) PackageInstallerCompat(io.github.muntashirakon.AppManager.apk.installer.PackageInstallerCompat) PackageUtils(io.github.muntashirakon.AppManager.utils.PackageUtils) FeatureController(io.github.muntashirakon.AppManager.settings.FeatureController) PackageManager(android.content.pm.PackageManager) ProfileManager(io.github.muntashirakon.AppManager.profiles.ProfileManager) Spannable(android.text.Spannable) MaterialAlertDialogBuilder(com.google.android.material.dialog.MaterialAlertDialogBuilder) UIUtils.getTitleText(io.github.muntashirakon.AppManager.utils.UIUtils.getTitleText) ManifestViewerActivity(io.github.muntashirakon.AppManager.details.ManifestViewerActivity) Log(io.github.muntashirakon.AppManager.logs.Log) DrawableRes(androidx.annotation.DrawableRes) ScannerActivity(io.github.muntashirakon.AppManager.scanner.ScannerActivity) HIDDEN_API_ENFORCEMENT_DEFAULT(io.github.muntashirakon.AppManager.servermanager.ApplicationInfoCompat.HIDDEN_API_ENFORCEMENT_DEFAULT) AppManager(io.github.muntashirakon.AppManager.AppManager) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) HIDDEN_API_ENFORCEMENT_ENABLED(io.github.muntashirakon.AppManager.servermanager.ApplicationInfoCompat.HIDDEN_API_ENFORCEMENT_ENABLED) GuardedBy(androidx.annotation.GuardedBy) Locale(java.util.Locale) View(android.view.View) Button(android.widget.Button) RecyclerView(androidx.recyclerview.widget.RecyclerView) AppUsageStatsManager(io.github.muntashirakon.AppManager.usage.AppUsageStatsManager) BetterActivityResult(io.github.muntashirakon.AppManager.utils.BetterActivityResult) ApkUtils(io.github.muntashirakon.AppManager.apk.ApkUtils) PermissionUtils.hasDumpPermission(io.github.muntashirakon.AppManager.utils.PermissionUtils.hasDumpPermission) AppDetailsViewModel(io.github.muntashirakon.AppManager.details.AppDetailsViewModel) Utils.openAsFolderInFM(io.github.muntashirakon.AppManager.utils.Utils.openAsFolderInFM) ViewGroup(android.view.ViewGroup) UserPackagePair(io.github.muntashirakon.AppManager.types.UserPackagePair) TERMUX_PERM_RUN_COMMAND(io.github.muntashirakon.AppManager.utils.PermissionUtils.TERMUX_PERM_RUN_COMMAND) List(java.util.List) TextView(android.widget.TextView) TextUtils(com.android.internal.util.TextUtils) SwipeRefreshLayout(io.github.muntashirakon.widget.SwipeRefreshLayout) ProfileMetaManager(io.github.muntashirakon.AppManager.profiles.ProfileMetaManager) ApplicationInfo(android.content.pm.ApplicationInfo) Signature(android.content.pm.Signature) ColorRes(androidx.annotation.ColorRes) AppDetailsItem(io.github.muntashirakon.AppManager.details.struct.AppDetailsItem) Typeface(android.graphics.Typeface) HIDDEN_API_ENFORCEMENT_BLACK(io.github.muntashirakon.AppManager.servermanager.ApplicationInfoCompat.HIDDEN_API_ENFORCEMENT_BLACK) Context(android.content.Context) TextInputEditText(com.google.android.material.textfield.TextInputEditText) AlertDialog(androidx.appcompat.app.AlertDialog) AppDetailsFragment(io.github.muntashirakon.AppManager.details.AppDetailsFragment) Pair(android.util.Pair) Intent(android.content.Intent) MainThread(androidx.annotation.MainThread) HashMap(java.util.HashMap) Ops(io.github.muntashirakon.AppManager.settings.Ops) PackageInfo(android.content.pm.PackageInfo) AtomicReference(java.util.concurrent.atomic.AtomicReference) FmProvider(io.github.muntashirakon.AppManager.fm.FmProvider) MenuItem(android.view.MenuItem) ClipData(android.content.ClipData) ApkFile(io.github.muntashirakon.AppManager.apk.ApkFile) MaterialButton(com.google.android.material.button.MaterialButton) SharedPrefsActivity(io.github.muntashirakon.AppManager.sharedpref.SharedPrefsActivity) ArrayUtils(io.github.muntashirakon.AppManager.utils.ArrayUtils) Build(android.os.Build) ExecutorService(java.util.concurrent.ExecutorService) OutputStream(java.io.OutputStream) LayoutInflater(android.view.LayoutInflater) ActivityCompat(androidx.core.app.ActivityCompat) RulesTypeSelectionDialogFragment(io.github.muntashirakon.AppManager.rules.RulesTypeSelectionDialogFragment) MagiskDenyList(io.github.muntashirakon.AppManager.magisk.MagiskDenyList) ScrollableDialogBuilder(io.github.muntashirakon.dialog.ScrollableDialogBuilder) ResolveInfo(android.content.pm.ResolveInfo) DialogTitleBuilder(io.github.muntashirakon.dialog.DialogTitleBuilder) Bitmap(android.graphics.Bitmap) MagiskProcess(io.github.muntashirakon.AppManager.magisk.MagiskProcess) Collections(java.util.Collections) MimeTypeMap(android.webkit.MimeTypeMap) ActivityResult(androidx.activity.result.ActivityResult) AlertDialog(androidx.appcompat.app.AlertDialog) ApkFile(io.github.muntashirakon.AppManager.apk.ApkFile) Chip(com.google.android.material.chip.Chip) SearchableMultiChoiceDialogBuilder(io.github.muntashirakon.AppManager.types.SearchableMultiChoiceDialogBuilder) Button(android.widget.Button) MaterialButton(com.google.android.material.button.MaterialButton) SsaidSettings(io.github.muntashirakon.AppManager.ssaid.SsaidSettings) TextInputLayout(com.google.android.material.textfield.TextInputLayout) DialogTitleBuilder(io.github.muntashirakon.dialog.DialogTitleBuilder) ClipboardManager(android.content.ClipboardManager) Intent(android.content.Intent) AtomicReference(java.util.concurrent.atomic.AtomicReference) IOException(java.io.IOException) ComponentRule(io.github.muntashirakon.AppManager.rules.struct.ComponentRule) MaterialAlertDialogBuilder(com.google.android.material.dialog.MaterialAlertDialogBuilder) ImageView(android.widget.ImageView) View(android.view.View) RecyclerView(androidx.recyclerview.widget.RecyclerView) TextView(android.widget.TextView) LogViewerActivity(io.github.muntashirakon.AppManager.logcat.LogViewerActivity) TextInputEditText(com.google.android.material.textfield.TextInputEditText) RemoteException(android.os.RemoteException) ClipData(android.content.ClipData) SpannableStringBuilder(android.text.SpannableStringBuilder) UiThread(androidx.annotation.UiThread)

Example 4 with SsaidSettings

use of io.github.muntashirakon.AppManager.ssaid.SsaidSettings in project AppManager by MuntashirAkon.

the class AppInfoViewModel method loadTagCloud.

@WorkerThread
public void loadTagCloud() {
    if (mainModel == null)
        return;
    PackageInfo packageInfo = mainModel.getPackageInfo();
    if (packageInfo == null)
        return;
    String packageName = packageInfo.packageName;
    ApplicationInfo applicationInfo = packageInfo.applicationInfo;
    TagCloud tagCloud = new TagCloud();
    try {
        HashMap<String, RuleType> trackerComponents = ComponentUtils.getTrackerComponentsForPackageInfo(packageInfo);
        tagCloud.trackerComponents = new ArrayList<>(trackerComponents.size());
        for (String component : trackerComponents.keySet()) {
            ComponentRule componentRule = mainModel.getComponentRule(component);
            if (componentRule == null) {
                componentRule = new ComponentRule(packageName, component, trackerComponents.get(component), AppPref.getDefaultComponentStatus());
            }
            tagCloud.trackerComponents.add(componentRule);
            tagCloud.areAllTrackersBlocked &= componentRule.isBlocked();
        }
        tagCloud.isSystemApp = (applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
        tagCloud.isSystemlessPath = !mainModel.getIsExternalApk() && Ops.isRoot() && MagiskUtils.isSystemlessPath(PackageUtils.getHiddenCodePathOrDefault(packageName, applicationInfo.publicSourceDir));
        tagCloud.isUpdatedSystemApp = (applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
        tagCloud.splitCount = mainModel.getSplitCount();
        tagCloud.isDebuggable = (applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
        tagCloud.isTestOnly = (applicationInfo.flags & ApplicationInfo.FLAG_TEST_ONLY) != 0;
        tagCloud.hasCode = (applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0;
        tagCloud.hasRequestedLargeHeap = (applicationInfo.flags & ApplicationInfo.FLAG_LARGE_HEAP) != 0;
        tagCloud.runningServices = ActivityManagerCompat.getRunningServices(packageName, mainModel.getUserHandle());
        tagCloud.isForceStopped = (applicationInfo.flags & ApplicationInfo.FLAG_STOPPED) != 0;
        tagCloud.isAppEnabled = applicationInfo.enabled;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            tagCloud.isAppSuspended = (applicationInfo.flags & ApplicationInfo.FLAG_SUSPENDED) != 0;
        }
        int privateFlags = ApplicationInfoCompat.getPrivateFlags(applicationInfo);
        tagCloud.isAppHidden = (privateFlags & ApplicationInfoCompat.PRIVATE_FLAG_HIDDEN) != 0;
        tagCloud.magiskHiddenProcesses = new ArrayList<>(MagiskHide.getProcesses(packageInfo));
        boolean magiskHideEnabled = false;
        for (MagiskProcess magiskProcess : tagCloud.magiskHiddenProcesses) {
            magiskHideEnabled |= magiskProcess.isEnabled();
            for (ActivityManager.RunningServiceInfo info : tagCloud.runningServices) {
                if (info.process.startsWith(magiskProcess.name)) {
                    magiskProcess.setRunning(true);
                }
            }
        }
        tagCloud.isMagiskHideEnabled = !mainModel.getIsExternalApk() && magiskHideEnabled;
        tagCloud.magiskDeniedProcesses = new ArrayList<>(MagiskDenyList.getProcesses(packageInfo));
        boolean magiskDenyListEnabled = false;
        for (MagiskProcess magiskProcess : tagCloud.magiskDeniedProcesses) {
            magiskDenyListEnabled |= magiskProcess.isEnabled();
            for (ActivityManager.RunningServiceInfo info : tagCloud.runningServices) {
                if (info.process.startsWith(magiskProcess.name)) {
                    magiskProcess.setRunning(true);
                }
            }
        }
        tagCloud.isMagiskDenyListEnabled = !mainModel.getIsExternalApk() && magiskDenyListEnabled;
        tagCloud.hasKeyStoreItems = KeyStoreUtils.hasKeyStore(applicationInfo.uid);
        tagCloud.hasMasterKeyInKeyStore = KeyStoreUtils.hasMasterKey(applicationInfo.uid);
        tagCloud.usesPlayAppSigning = PackageUtils.usesPlayAppSigning(applicationInfo);
        try {
            tagCloud.backups = MetadataManager.getMetadata(packageName);
        } catch (IOException e) {
            tagCloud.backups = ArrayUtils.emptyArray(MetadataManager.Metadata.class);
        }
        if (!mainModel.getIsExternalApk() && PermissionUtils.hasDumpPermission()) {
            String targetString = "user," + packageName + "," + applicationInfo.uid;
            Runner.Result result = Runner.runCommand(new String[] { "dumpsys", "deviceidle", "whitelist" });
            tagCloud.isBatteryOptimized = !result.isSuccessful() || !result.getOutput().contains(targetString);
        } else {
            tagCloud.isBatteryOptimized = true;
        }
        if (!mainModel.getIsExternalApk() && LocalServer.isAMServiceAlive()) {
            tagCloud.netPolicies = NetworkPolicyManagerCompat.getUidPolicy(applicationInfo.uid);
        } else {
            tagCloud.netPolicies = 0;
        }
        if (Ops.isRoot() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            try {
                tagCloud.ssaid = new SsaidSettings(packageName, applicationInfo.uid).getSsaid();
                if (TextUtils.isEmpty(tagCloud.ssaid))
                    tagCloud.ssaid = null;
            } catch (IOException ignore) {
            }
        }
        if (Ops.isRoot()) {
            List<UriManager.UriGrant> uriGrants = new UriManager().getGrantedUris(packageName);
            if (uriGrants != null) {
                Iterator<UriManager.UriGrant> uriGrantIterator = uriGrants.listIterator();
                UriManager.UriGrant uriGrant;
                while (uriGrantIterator.hasNext()) {
                    uriGrant = uriGrantIterator.next();
                    if (uriGrant.targetUserId != mainModel.getUserHandle()) {
                        uriGrantIterator.remove();
                    }
                }
                tagCloud.uriGrants = uriGrants;
            }
        }
    } catch (Throwable th) {
        // Unknown behaviour
        throw new RuntimeException(th);
    } finally {
        this.tagCloud.postValue(tagCloud);
    }
}
Also used : Runner(io.github.muntashirakon.AppManager.runner.Runner) ApplicationInfo(android.content.pm.ApplicationInfo) ActivityManager(android.app.ActivityManager) SsaidSettings(io.github.muntashirakon.AppManager.ssaid.SsaidSettings) MagiskProcess(io.github.muntashirakon.AppManager.magisk.MagiskProcess) PackageInfo(android.content.pm.PackageInfo) RuleType(io.github.muntashirakon.AppManager.rules.RuleType) IOException(java.io.IOException) ComponentRule(io.github.muntashirakon.AppManager.rules.struct.ComponentRule) MetadataManager(io.github.muntashirakon.AppManager.backup.MetadataManager) UriManager(io.github.muntashirakon.AppManager.uri.UriManager) WorkerThread(androidx.annotation.WorkerThread)

Aggregations

SsaidSettings (io.github.muntashirakon.AppManager.ssaid.SsaidSettings)4 ComponentName (android.content.ComponentName)3 Runner (io.github.muntashirakon.AppManager.runner.Runner)3 UriManager (io.github.muntashirakon.AppManager.uri.UriManager)3 IOException (java.io.IOException)3 INotificationManager (android.app.INotificationManager)2 ApplicationInfo (android.content.pm.ApplicationInfo)2 PackageInfo (android.content.pm.PackageInfo)2 RemoteException (android.os.RemoteException)2 NonNull (androidx.annotation.NonNull)2 AppOpsService (io.github.muntashirakon.AppManager.appops.AppOpsService)2 PseudoRules (io.github.muntashirakon.AppManager.rules.PseudoRules)2 Path (io.github.muntashirakon.io.Path)2 ArrayList (java.util.ArrayList)2 Manifest (android.Manifest)1 ActivityManager (android.app.ActivityManager)1 ClipData (android.content.ClipData)1 ClipboardManager (android.content.ClipboardManager)1 Context (android.content.Context)1 Intent (android.content.Intent)1