Skip to content

Commit

Permalink
[AppInfo] Add a new tag: Bloatware
Browse files Browse the repository at this point in the history
Clicking on the tag opens a dialog containing description, dependencies,
alternatives, etc. like in the Debloater page

Signed-off-by: Muntashir Al-Islam <muntashirakon@riseup.net>
  • Loading branch information
MuntashirAkon committed Jul 12, 2023
1 parent 92f4d87 commit cda119a
Show file tree
Hide file tree
Showing 8 changed files with 184 additions and 123 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,37 @@

package io.github.muntashirakon.AppManager;

import android.content.Context;
import android.content.res.Resources;
import android.util.DisplayMetrics;

import androidx.annotation.NonNull;
import androidx.annotation.WorkerThread;
import androidx.collection.ArrayMap;
import androidx.core.os.ConfigurationCompat;
import androidx.core.os.LocaleListCompat;

import com.google.gson.Gson;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import io.github.muntashirakon.AppManager.db.utils.AppDb;
import io.github.muntashirakon.AppManager.debloat.DebloatObject;
import io.github.muntashirakon.AppManager.debloat.SuggestionObject;
import io.github.muntashirakon.AppManager.misc.VMRuntime;
import io.github.muntashirakon.AppManager.utils.ContextUtils;
import io.github.muntashirakon.AppManager.utils.FileUtils;

public class StaticDataset {
private static String[] sTrackerCodeSignatures;
private static String[] sTrackerNames;
private static List<DebloatObject> sDebloatObjects;

public static final String ARMEABI_V7A = "armeabi_v7a";
public static final String ARM64_V8A = "arm64_v8a";
Expand Down Expand Up @@ -81,4 +95,65 @@ public static String[] getTrackerNames() {
}
return sTrackerNames;
}

@WorkerThread
public static List<DebloatObject> getDebloatObjects() {
if (sDebloatObjects == null) {
sDebloatObjects = loadDebloatObjects(ContextUtils.getContext(), new Gson());
}
return sDebloatObjects;
}

@WorkerThread
public static List<DebloatObject> getDebloatObjectsWithInstalledInfo(@NonNull Context context) {
AppDb appDb = new AppDb();
if (sDebloatObjects == null) {
sDebloatObjects = loadDebloatObjects(context, new Gson());
}
for (DebloatObject debloatObject : sDebloatObjects) {
debloatObject.fillInstallInfo(context, appDb);
}
return sDebloatObjects;
}

@NonNull
@WorkerThread
private static List<DebloatObject> loadDebloatObjects(@NonNull Context context, @NonNull Gson gson) {
HashMap<String, List<SuggestionObject>> idSuggestionObjectsMap = loadSuggestions(context, gson);
String jsonContent = FileUtils.getContentFromAssets(context, "debloat.json");
try {
List<DebloatObject> debloatObjects = Arrays.asList(gson.fromJson(jsonContent, DebloatObject[].class));
for (DebloatObject debloatObject : debloatObjects) {
List<SuggestionObject> suggestionObjects = idSuggestionObjectsMap.get(debloatObject.getSuggestionId());
debloatObject.setSuggestions(suggestionObjects);
}
return debloatObjects;
} catch (Throwable e) {
e.printStackTrace();
return Collections.emptyList();
}
}

@NonNull
@WorkerThread
private static HashMap<String, List<SuggestionObject>> loadSuggestions(@NonNull Context context, @NonNull Gson gson) {
String jsonContent = FileUtils.getContentFromAssets(context, "suggestions.json");
HashMap<String, List<SuggestionObject>> idSuggestionObjectsMap = new HashMap<>();
try {
SuggestionObject[] suggestionObjects = gson.fromJson(jsonContent, SuggestionObject[].class);
if (suggestionObjects != null) {
for (SuggestionObject suggestionObject : suggestionObjects) {
List<SuggestionObject> objects = idSuggestionObjectsMap.get(suggestionObject.suggestionId);
if (objects == null) {
objects = new ArrayList<>();
idSuggestionObjectsMap.put(suggestionObject.suggestionId, objects);
}
objects.add(suggestionObject);
}
}
} catch (Throwable th) {
th.printStackTrace();
}
return idSuggestionObjectsMap;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

package io.github.muntashirakon.AppManager.debloat;

import android.app.Application;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
Expand All @@ -17,6 +18,8 @@
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.appcompat.widget.LinearLayoutCompat;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;

Expand All @@ -30,7 +33,10 @@
import java.util.List;

import io.github.muntashirakon.AppManager.R;
import io.github.muntashirakon.AppManager.StaticDataset;
import io.github.muntashirakon.AppManager.db.utils.AppDb;
import io.github.muntashirakon.AppManager.details.AppDetailsActivity;
import io.github.muntashirakon.AppManager.utils.ThreadUtils;
import io.github.muntashirakon.AppManager.utils.UIUtils;
import io.github.muntashirakon.AppManager.utils.appearance.ColorCodes;
import io.github.muntashirakon.dialog.CapsuleBottomSheetDialogFragment;
Expand Down Expand Up @@ -80,7 +86,7 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat
dismiss();
return;
}
DebloaterViewModel viewModel = new ViewModelProvider(requireActivity()).get(DebloaterViewModel.class);
BloatwareDetailsViewModel viewModel = new ViewModelProvider(requireActivity()).get(BloatwareDetailsViewModel.class);
mAppIconView = view.findViewById(R.id.icon);
mOpenAppInfoButton = view.findViewById(R.id.info);
mAppLabelView = view.findViewById(R.id.name);
Expand All @@ -94,7 +100,7 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat
mAdapter = new SuggestionsAdapter();
mSuggestionView.setAdapter(mAdapter);

viewModel.getDebloatObjectLiveData().observe(getViewLifecycleOwner(), debloatObject -> {
viewModel.debloatObjectLiveData.observe(getViewLifecycleOwner(), debloatObject -> {
if (debloatObject == null) {
dismiss();
return;
Expand All @@ -110,6 +116,7 @@ private void updateDialog(@NonNull DebloatObject debloatObject) {
mAppIconView.setImageDrawable(icon != null ? icon : requireActivity().getPackageManager().getDefaultActivityIcon());
int[] users = debloatObject.getUsers();
if (users != null && users.length > 0) {
mOpenAppInfoButton.setVisibility(View.VISIBLE);
mOpenAppInfoButton.setOnClickListener(v -> {
Intent appDetailsIntent = AppDetailsActivity.getIntent(requireContext(), debloatObject.packageName,
users[0]);
Expand All @@ -124,10 +131,11 @@ private void updateDialog(@NonNull DebloatObject debloatObject) {
mPackageNameView.setText(debloatObject.packageName);
String warning = debloatObject.getWarning();
if (warning != null) {
mWarningView.setVisibility(View.VISIBLE);
mWarningView.setText(warning);
if (debloatObject.getRemoval() != DebloatObject.REMOVAL_CAUTION) {
mWarningView.setAlertType(MaterialAlertView.ALERT_TYPE_INFO);
}
} else mWarningView.setAlertType(MaterialAlertView.ALERT_TYPE_WARN);
} else mWarningView.setVisibility(View.GONE);
mDescriptionView.setText(getDescription(debloatObject));
// Add tags
Expand Down Expand Up @@ -212,6 +220,28 @@ private void addTag(@NonNull ViewGroup parent, @NonNull CharSequence title) {
parent.addView(chip);
}

public static class BloatwareDetailsViewModel extends AndroidViewModel {
public final MutableLiveData<DebloatObject> debloatObjectLiveData = new MutableLiveData<>();

public BloatwareDetailsViewModel(@NonNull Application application) {
super(application);
}

public void findDebloatObject(@NonNull String packageName) {
ThreadUtils.postOnBackgroundThread(() -> {
List<DebloatObject> debloatObjects = StaticDataset.getDebloatObjects();
for (DebloatObject debloatObject : debloatObjects) {
if (packageName.equals(debloatObject.packageName)) {
debloatObject.fillInstallInfo(getApplication(), new AppDb());
debloatObjectLiveData.postValue(debloatObject);
return;
}
}
debloatObjectLiveData.postValue(null);
});
}
}

private class SuggestionsAdapter extends RecyclerView.Adapter<SuggestionsAdapter.SuggestionViewHolder> {
private final List<SuggestionObject> mSuggestions = Collections.synchronizedList(new ArrayList<>());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@

package io.github.muntashirakon.AppManager.debloat;

import static io.github.muntashirakon.AppManager.compat.PackageManagerCompat.MATCH_STATIC_SHARED_AND_SDK_LIBRARIES;
import static io.github.muntashirakon.AppManager.compat.PackageManagerCompat.MATCH_UNINSTALLED_PACKAGES;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.os.RemoteException;

import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
Expand All @@ -14,6 +21,10 @@
import java.lang.annotation.RetentionPolicy;
import java.util.List;

import io.github.muntashirakon.AppManager.compat.ApplicationInfoCompat;
import io.github.muntashirakon.AppManager.compat.PackageManagerCompat;
import io.github.muntashirakon.AppManager.db.entity.App;
import io.github.muntashirakon.AppManager.db.utils.AppDb;
import io.github.muntashirakon.AppManager.utils.ArrayUtils;

public class DebloatObject {
Expand Down Expand Up @@ -61,6 +72,7 @@ public class DebloatObject {
private Drawable mIcon;
@Nullable
private CharSequence mLabel;
@Nullable
private int[] mUsers;
private boolean mInstalled;
@Nullable
Expand Down Expand Up @@ -124,24 +136,17 @@ public CharSequence getLabel() {
return mLabel != null ? mLabel : mInternalLabel;
}

public void setLabel(@Nullable CharSequence label) {
mLabel = label;
}

@Nullable
public Drawable getIcon() {
return mIcon;
}

public void setIcon(@Nullable Drawable icon) {
mIcon = icon;
}

@Nullable
public int[] getUsers() {
return mUsers;
}

public void addUser(int userId) {
private void addUser(int userId) {
if (mUsers == null) {
mUsers = new int[]{userId};
} else {
Expand All @@ -153,10 +158,6 @@ public boolean isInstalled() {
return mInstalled;
}

public void setInstalled(boolean installed) {
mInstalled = installed;
}

public boolean isSystemApp() {
return Boolean.TRUE.equals(mSystemApp);
}
Expand All @@ -165,7 +166,42 @@ public boolean isUserApp() {
return Boolean.FALSE.equals(mSystemApp);
}

public void setSystemApp(@Nullable Boolean systemApp) {
mSystemApp = systemApp;
public void fillInstallInfo(@NonNull Context context, @NonNull AppDb appDb) {
PackageManager pm = context.getPackageManager();
List<SuggestionObject> suggestionObjects = getSuggestions();
if (suggestionObjects != null) {
for (SuggestionObject suggestionObject : suggestionObjects) {
List<App> apps = appDb.getAllApplications(suggestionObject.packageName);
for (App app : apps) {
if (app.isInstalled) {
suggestionObject.addUser(app.userId);
}
}
}
}
// Update application data
mInstalled = false;
mUsers = null;
List<App> apps = appDb.getAllApplications(packageName);
for (App app : apps) {
if (!app.isInstalled) {
continue;
}
mInstalled = true;
addUser(app.userId);
mSystemApp = app.isSystemApp();
mLabel = app.packageLabel;
if (getIcon() == null) {
try {
ApplicationInfo ai = PackageManagerCompat.getApplicationInfo(packageName,
MATCH_UNINSTALLED_PACKAGES | MATCH_STATIC_SHARED_AND_SDK_LIBRARIES, app.userId);
mInstalled = (ai.flags & ApplicationInfo.FLAG_INSTALLED) != 0;
mSystemApp = ApplicationInfoCompat.isSystemApp(ai);
mLabel = ai.loadLabel(pm);
mIcon = ai.loadIcon(pm);
} catch (RemoteException | PackageManager.NameNotFoundException ignore) {
}
}
}
}
}
Loading

0 comments on commit cda119a

Please sign in to comment.