Repo created

This commit is contained in:
Fr4nz D13trich 2025-11-20 16:34:49 +01:00
parent 21de94943c
commit 4e2998210b
143 changed files with 10606 additions and 2 deletions

View file

@ -0,0 +1,91 @@
package com.sunilpaulmathew.debloater;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.textview.MaterialTextView;
import com.sunilpaulmathew.debloater.fragments.AboutFragment;
import com.sunilpaulmathew.debloater.fragments.ActivePackagesFragment;
import com.sunilpaulmathew.debloater.fragments.InactivePackagesFragment;
import com.sunilpaulmathew.debloater.utils.UpdateCheck;
import com.sunilpaulmathew.debloater.utils.Utils;
import in.sunilpaulmathew.sCommon.Adapters.sPagerAdapter;
import in.sunilpaulmathew.sCommon.CommonUtils.sCommonUtils;
import in.sunilpaulmathew.sCommon.PackageUtils.sPackageUtils;
import in.sunilpaulmathew.sCommon.ThemeUtils.sThemeUtils;
/*
* Created by sunilpaulmathew <sunil.kde@gmail.com> on October 27, 2020
*/
public class MainActivity extends AppCompatActivity {
private Fragment mFragment;
@SuppressLint("NonConstantResourceId")
@Override
protected void onCreate(Bundle savedInstanceState) {
//Initialize App Theme
sThemeUtils.initializeAppTheme(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BottomNavigationView mBottomNav = findViewById(R.id.bottom_navigation);
MaterialTextView mUnSupported = findViewById(R.id.unsupported);
if (!Utils.rootAccess()) {
mUnSupported.setText(R.string.no_root);
mUnSupported.setVisibility(View.VISIBLE);
return;
} else if (!Utils.magiskSupported()) {
mUnSupported.setText(R.string.no_magisk);
mUnSupported.setVisibility(View.VISIBLE);
return;
}
sPagerAdapter adapter = new sPagerAdapter(getSupportFragmentManager());
adapter.AddFragment(new ActivePackagesFragment(), null);
adapter.AddFragment(new InactivePackagesFragment(), null);
adapter.AddFragment(new AboutFragment(), null);
mBottomNav.setOnItemSelectedListener(
menuItem -> {
if (menuItem.getItemId() == R.id.nav_active) {
mFragment = new ActivePackagesFragment();
} else if (menuItem.getItemId() == R.id.nav_inactive) {
mFragment = new InactivePackagesFragment();
} else if (menuItem.getItemId() == R.id.nav_about) {
mFragment = new AboutFragment();
}
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
mFragment).commit();
return true;
}
);
mBottomNav.setVisibility(View.VISIBLE);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
new ActivePackagesFragment()).commit();
}
}
@Override
public void onStart() {
super.onStart();
if (Utils.rootAccess() && Utils.magiskSupported() && !sPackageUtils.isPackageInstalled("com.android.vending",
this) && sCommonUtils.getInt("update_enabled", 2, this) == 0 && UpdateCheck.isSignatureMatched(this)) {
new UpdateCheck().initialize(1, this);
}
}
}

View file

@ -0,0 +1,44 @@
package com.sunilpaulmathew.debloater.activities;
import android.annotation.SuppressLint;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.material.textview.MaterialTextView;
import com.sunilpaulmathew.debloater.BuildConfig;
import com.sunilpaulmathew.debloater.R;
import java.io.IOException;
import in.sunilpaulmathew.sCommon.FileUtils.sFileUtils;
import in.sunilpaulmathew.sCommon.JsonUtils.sJSONUtils;
import in.sunilpaulmathew.sCommon.PackageUtils.sPackageUtils;
/*
* Created by sunilpaulmathew <sunil.kde@gmail.com> on December 28, 2020
*/
public class ChangeLogActivity extends AppCompatActivity {
@SuppressLint("SetTextI18n")
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_changelog);
MaterialTextView mChangeLog = findViewById(R.id.change_log);
MaterialTextView mTitle = findViewById(R.id.app_title);
MaterialTextView mCancel = findViewById(R.id.cancel_button);
mTitle.setText(getString(R.string.app_name) + (sPackageUtils.isPackageInstalled("com.android.vending",
this) ? " Pro " : " ") + BuildConfig.VERSION_NAME);
try {
mChangeLog.setText(sJSONUtils.getString(sJSONUtils.getJSONObject(sFileUtils.readAssetFile(
"release.json", this)), "fullReleaseNotes"));
} catch (IOException ignored) {
}
mCancel.setOnClickListener(v -> finish());
}
}

View file

@ -0,0 +1,78 @@
package com.sunilpaulmathew.debloater.activities;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.ProgressBar;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.material.card.MaterialCardView;
import com.google.android.material.textview.MaterialTextView;
import com.sunilpaulmathew.debloater.MainActivity;
import com.sunilpaulmathew.debloater.R;
import com.sunilpaulmathew.debloater.utils.Common;
import com.sunilpaulmathew.debloater.utils.PackageTasks;
import in.sunilpaulmathew.sCommon.CommonUtils.sCommonUtils;
import in.sunilpaulmathew.sCommon.CommonUtils.sExecutor;
/*
* Created by sunilpaulmathew <sunil.kde@gmail.com> on November 1, 2020
*/
public class StartActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_start);
MaterialCardView mStartCard = findViewById(R.id.start_card);
MaterialTextView mWarning = findViewById(R.id.warning);
ProgressBar mProgress = findViewById(R.id.progress);
if (!sCommonUtils.getBoolean("warning_message", false, this)) {
mProgress.setVisibility(View.GONE);
mWarning.setVisibility(View.VISIBLE);
mStartCard.setVisibility(View.VISIBLE);
} else {
loadUI(StartActivity.this);
}
mStartCard.setOnClickListener(v -> {
mProgress.setVisibility(View.VISIBLE);
mWarning.setVisibility(View.GONE);
mStartCard.setVisibility(View.GONE);
loadUI(StartActivity.this);
});
}
private static void loadUI(Activity activity) {
new sExecutor() {
@Override
public void onPreExecute() {
if (!sCommonUtils.getBoolean("warning_message", false, activity)) {
sCommonUtils.saveBoolean("warning_message", true, activity);
}
}
@Override
public void doInBackground() {
// Acquire information about installed apps
Common.setRawData(PackageTasks.getRawData(activity));
}
@Override
public void onPostExecute() {
// Launch MainActivity
Intent mainActivity = new Intent(activity, MainActivity.class);
activity.startActivity(mainActivity);
activity.finish();
}
}.execute();
}
}

View file

@ -0,0 +1,62 @@
package com.sunilpaulmathew.debloater.activities;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import androidx.appcompat.app.AppCompatActivity;
import com.sunilpaulmathew.debloater.R;
import com.sunilpaulmathew.debloater.fragments.TomatotDebloaterFragment;
import com.sunilpaulmathew.debloater.utils.Tomatot;
import in.sunilpaulmathew.sCommon.CommonUtils.sExecutor;
import in.sunilpaulmathew.sCommon.ThemeUtils.sThemeUtils;
/*
* Created by sunilpaulmathew <sunil.kde@gmail.com> on November 4, 2020
*/
public class TomatotActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_custom_scripts);
FrameLayout mFrameLayout = findViewById(R.id.fragment_container);
LinearLayout mLinearLayout = findViewById(R.id.layout_main);
ProgressBar mProgressBar = findViewById(R.id.progress);
new sExecutor() {
@Override
public void onPreExecute() {
if (sThemeUtils.isDarkTheme(TomatotActivity.this)) {
mLinearLayout.setBackgroundColor(Color.BLACK);
} else {
mLinearLayout.setBackgroundColor(Color.WHITE);
}
}
@Override
public void doInBackground() {
Tomatot.setInvisibleData(TomatotActivity.this);
Tomatot.setLightData(TomatotActivity.this);
Tomatot.setExtremeData(TomatotActivity.this);
}
@Override
public void onPostExecute() {
mProgressBar.setVisibility(View.GONE);
mFrameLayout.setVisibility(View.VISIBLE);
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
new TomatotDebloaterFragment()).commit();
}
}.execute();
}
}

View file

@ -0,0 +1,75 @@
package com.sunilpaulmathew.debloater.activities;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import androidx.appcompat.app.AppCompatActivity;
import com.sunilpaulmathew.debloater.R;
import com.sunilpaulmathew.debloater.fragments.UADFragment;
import com.sunilpaulmathew.debloater.utils.Common;
import com.sunilpaulmathew.debloater.utils.UAD;
import in.sunilpaulmathew.sCommon.CommonUtils.sExecutor;
import in.sunilpaulmathew.sCommon.ThemeUtils.sThemeUtils;
/*
* Created by sunilpaulmathew <sunil.kde@gmail.com> on January 26, 2020
*/
public class UADActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_custom_scripts);
FrameLayout mFrameLayout = findViewById(R.id.fragment_container);
LinearLayout mLinearLayout = findViewById(R.id.layout_main);
ProgressBar mProgressBar = findViewById(R.id.progress);
new sExecutor() {
@Override
public void onPreExecute() {
if (sThemeUtils.isDarkTheme(UADActivity.this)) {
mLinearLayout.setBackgroundColor(Color.BLACK);
} else {
mLinearLayout.setBackgroundColor(Color.WHITE);
}
}
@Override
public void doInBackground() {
UAD.setUADData(UAD.getCarrier(), Common.getCarrier(), UADActivity.this);
UAD.setUADData(UAD.getHuawei(), Common.getHuawei(), UADActivity.this);
UAD.setUADData(UAD.getLG(), Common.getLG(), UADActivity.this);
UAD.setUADData(UAD.getMiscellaneous(), Common.getMisc(), UADActivity.this);
UAD.setUADData(UAD.getMotorola(), Common.getMoto(), UADActivity.this);
UAD.setUADData(UAD.getNokia(), Common.getNokia(), UADActivity.this);
UAD.setUADData(UAD.getOppo(), Common.getOppo(), UADActivity.this);
UAD.setUADData(UAD.getSamsung(), Common.getSamsung(), UADActivity.this);
UAD.setUADData(UAD.getSony(), Common.getSony(), UADActivity.this);
UAD.setUADData(UAD.getXiaomi(), Common.getXiaomi(), UADActivity.this);
UAD.setUADData(UAD.getZTE(), Common.getZTE(), UADActivity.this);
UAD.setUADData(UAD.getAOSP(), Common.getAOSP(), UADActivity.this);
UAD.setUADData(UAD.getGoogle(), Common.getGoogle(), UADActivity.this);
UAD.setUADData(UAD.getASUS(), Common.getAsus(), UADActivity.this);
UAD.setUADData(UAD.getOnePlus(), Common.getOnePlus(), UADActivity.this);
}
@Override
public void onPostExecute() {
mProgressBar.setVisibility(View.GONE);
mFrameLayout.setVisibility(View.VISIBLE);
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
new UADFragment()).commit();
}
}.execute();
}
}

View file

@ -0,0 +1,123 @@
package com.sunilpaulmathew.debloater.adapters;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.net.Uri;
import android.provider.Settings;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.AppCompatImageButton;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.textview.MaterialTextView;
import com.sunilpaulmathew.debloater.BuildConfig;
import com.sunilpaulmathew.debloater.R;
import com.sunilpaulmathew.debloater.activities.ChangeLogActivity;
import com.sunilpaulmathew.debloater.utils.Common;
import com.sunilpaulmathew.debloater.utils.UpdateCheck;
import com.sunilpaulmathew.debloater.utils.Utils;
import java.util.List;
import in.sunilpaulmathew.sCommon.CommonUtils.sCommonUtils;
import in.sunilpaulmathew.sCommon.CommonUtils.sSerializableItems;
import in.sunilpaulmathew.sCommon.Credits.sCreditsUtils;
import in.sunilpaulmathew.sCommon.ThemeUtils.sThemeUtils;
import in.sunilpaulmathew.sCommon.TranslatorUtils.sTranslatorUtils;
/*
* Created by sunilpaulmathew <sunil.kde@gmail.com> on February 03, 2021
*/
public class AboutAdapter extends RecyclerView.Adapter<AboutAdapter.ViewHolder> {
private final List<sSerializableItems> data;
public AboutAdapter(List<sSerializableItems> data) {
this.data = data;
}
@NonNull
@Override
public AboutAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View rowItem = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycle_view_about, parent, false);
return new AboutAdapter.ViewHolder(rowItem);
}
@SuppressLint("UseCompatLoadingForDrawables")
@Override
public void onBindViewHolder(@NonNull AboutAdapter.ViewHolder holder, int position) {
holder.Title.setText(this.data.get(position).getTextOne());
if (sThemeUtils.isDarkTheme(holder.Title.getContext())) {
holder.Title.setTextColor(Utils.getThemeAccentColor(holder.Title.getContext()));
} else if (position != 0 && !this.data.get(position).getTextOne().equals(holder.Title.getContext()
.getString(R.string.fdroid)) && !this.data.get(position).getTextTwo().equals(holder.Title
.getContext().getString(R.string.translations))) {
holder.mIcon.setColorFilter(Color.BLACK);
}
holder.Description.setText(this.data.get(position).getTextTwo());
holder.mIcon.setImageDrawable(this.data.get(position).getIcon());
holder.mRVLayout.setOnClickListener(v -> {
if (this.data.get(position).getTextThree() != null) {
sCommonUtils.launchUrl(this.data.get(position).getTextThree(), (Activity) holder.mRVLayout.getContext());
} else if (position == 0) {
Intent settings = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
settings.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Uri uri = Uri.fromParts("package", BuildConfig.APPLICATION_ID, null);
settings.setData(uri);
holder.mRVLayout.getContext().startActivity(settings);
} else if (position == 4) {
Intent changeLog = new Intent(holder.mRVLayout.getContext(), ChangeLogActivity.class);
holder.mRVLayout.getContext().startActivity(changeLog);
} else if (position == 7) {
UpdateCheck.isManualUpdate(true);
new UpdateCheck().initialize(0, (Activity) holder.mRVLayout.getContext());
} else if (position == 8) {
new sTranslatorUtils(v.getContext().getString(R.string.app_name), "https://poeditor.com/join/project?hash=BZS89Ev3WG",
(Activity) v.getContext()).show();
} else if (position == 9) {
new sCreditsUtils(Common.getCredits(),
sCommonUtils.getDrawable(R.mipmap.ic_launcher, v.getContext()),
sCommonUtils.getDrawable(R.drawable.ic_back, v.getContext()),
holder.Title.getCurrentTextColor(), 20, v.getContext().getString(R.string.app_name),
"2020-2025, sunilpaulmathew", BuildConfig.VERSION_NAME)
.launchCredits(v.getContext());
} else if (position == 10) {
Intent shareapp = new Intent();
shareapp.setAction(Intent.ACTION_SEND);
shareapp.putExtra(Intent.EXTRA_SUBJECT, holder.mRVLayout.getContext().getString(R.string.app_name));
shareapp.putExtra(Intent.EXTRA_TEXT, holder.mRVLayout.getContext().getString(R.string.share_app_message, BuildConfig.VERSION_NAME) + Utils.getAppStoreURL(holder.mRVLayout.getContext()));
shareapp.setType("text/plain");
Intent shareIntent = Intent.createChooser(shareapp, null);
holder.mRVLayout.getContext().startActivity(shareIntent);
}
});
}
@Override
public int getItemCount() {
return this.data.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
private final AppCompatImageButton mIcon;
private final MaterialTextView Title;
private final MaterialTextView Description;
private final LinearLayout mRVLayout;
public ViewHolder(View view) {
super(view);
this.mIcon = view.findViewById(R.id.icon);
this.Title = view.findViewById(R.id.title);
this.Description = view.findViewById(R.id.description);
this.mRVLayout = view.findViewById(R.id.rv_about);
}
}
}

View file

@ -0,0 +1,137 @@
package com.sunilpaulmathew.debloater.adapters;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.graphics.Color;
import android.net.Uri;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.AppCompatImageButton;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.textview.MaterialTextView;
import com.sunilpaulmathew.debloater.R;
import com.sunilpaulmathew.debloater.utils.Common;
import com.sunilpaulmathew.debloater.utils.PackageItem;
import com.sunilpaulmathew.debloater.utils.PackageTasks;
import com.sunilpaulmathew.debloater.utils.Utils;
import java.util.List;
import in.sunilpaulmathew.sCommon.CommonUtils.sCommonUtils;
import in.sunilpaulmathew.sCommon.ThemeUtils.sThemeUtils;
/*
* Created by sunilpaulmathew <sunil.kde@gmail.com> on February 03, 2021
*/
public class ActivePackagesAdapter extends RecyclerView.Adapter<ActivePackagesAdapter.ViewHolder> {
private final List<PackageItem> data;
private final String searchText;
public ActivePackagesAdapter(List<PackageItem> data, String searchText) {
this.data = data;
this.searchText = searchText;
}
@NonNull
@Override
public ActivePackagesAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View rowItem = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycle_view_layout, parent, false);
return new ActivePackagesAdapter.ViewHolder(rowItem);
}
@SuppressLint("UseCompatLoadingForDrawables")
@Override
public void onBindViewHolder(@NonNull ActivePackagesAdapter.ViewHolder holder, int position) {
try {
holder.mIcon.setImageDrawable(this.data.get(position).getAppIcon());
if (this.data.get(position).getPackageName() != null) {
holder.mPackageName.setText(this.data.get(position).getPackageName());
holder.mPackageName.setVisibility(View.VISIBLE);
holder.mPackageName.setTextColor(Color.RED);
} else {
holder.mPackageName.setVisibility(View.GONE);
}
holder.mPath.setText(this.data.get(position).getAPKPath());
if (searchText != null && Common.isTextMatched(this.data.get(position).getAppName(), searchText)) {
holder.mName.setText(Utils.fromHtml(this.data.get(position).getAppName().replace(searchText,
"<b><i><font color=\"" + Color.RED + "\">" + searchText + "</font></i></b>")));
} else {
holder.mName.setText(this.data.get(position).getAppName());
}
if (sThemeUtils.isDarkTheme(holder.mName.getContext())) {
holder.mName.setTextColor(Utils.getThemeAccentColor(holder.mName.getContext()));
}
if (Utils.exist(PackageTasks.getModulePath() + this.data.get(position).getAPKPath()) || Utils.exist(PackageTasks.getModulePath() + PackageTasks.getAdjAPKPath(this.data.get(position).getAPKPath()))) {
holder.actionMessage.setText(holder.actionLayout.getContext().getString(R.string.restore));
holder.mActionIcon.setImageDrawable(sCommonUtils.getDrawable(R.drawable.ic_restore, holder.actionLayout.getContext()));
holder.statusMessage.setTextColor(Color.RED);
holder.statusMessage.setVisibility(View.VISIBLE);
holder.actionMessage.setTextColor(Color.GREEN);
holder.mActionIcon.setColorFilter(Color.GREEN);
holder.statusMessage.setText(holder.actionLayout.getContext().getString(R.string.status_message_remove));
} else {
holder.actionMessage.setText(holder.actionLayout.getContext().getString(R.string.remove));
holder.mActionIcon.setImageDrawable(sCommonUtils.getDrawable(R.drawable.ic_delete, holder.actionLayout.getContext()));
holder.statusMessage.setTextColor(Color.GREEN);
holder.statusMessage.setVisibility(View.GONE);
holder.actionMessage.setTextColor(Color.RED);
holder.mActionIcon.setColorFilter(Color.RED);
holder.statusMessage.setText(null);
}
holder.actionLayout.setOnClickListener(v -> {
if (Utils.exist(PackageTasks.getModulePath() + this.data.get(position).getAPKPath()) || Utils.exist(PackageTasks.getModulePath() + PackageTasks.getAdjAPKPath(this.data.get(position).getAPKPath()))) {
PackageTasks.revertDelete(PackageTasks.getAdjAPKPath(this.data.get(position).getAPKPath()));
} else {
if (data.get(position).isUpdatedSystemApp()) {
new MaterialAlertDialogBuilder(v.getContext())
.setIcon(data.get(position).getAppIcon())
.setTitle(data.get(position).getAppName())
.setMessage(v.getContext().getString(R.string.updated_system_app_warning, data.get(position).getAppName()))
.setNegativeButton(R.string.cancel, (dialog, id) -> {
})
.setPositiveButton(R.string.uninstall, (dialog, id) -> {
Intent remove = new Intent(Intent.ACTION_DELETE);
remove.putExtra(Intent.EXTRA_RETURN_RESULT, true);
remove.setData(Uri.parse("package:" + data.get(position).getPackageName()));
v.getContext().startActivity(remove);
}).show();
}
PackageTasks.setToDelete(PackageTasks.getAdjAPKPath(this.data.get(position).getAPKPath()), holder.mName.getText().toString());
}
notifyItemChanged(position);
});
} catch (NullPointerException ignored) {}
}
@Override
public int getItemCount() {
return this.data.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
private final AppCompatImageButton mActionIcon, mIcon;
private final MaterialTextView mName, mPackageName, mPath, actionMessage, statusMessage;
private final FrameLayout actionLayout;
public ViewHolder(View view) {
super(view);
this.mActionIcon = view.findViewById(R.id.action_icon);
this.mIcon = view.findViewById(R.id.icon);
this.mName = view.findViewById(R.id.title);
this.mPackageName = view.findViewById(R.id.packageName);
this.mPath = view.findViewById(R.id.description);
this.actionMessage = view.findViewById(R.id.action_message);
this.statusMessage = view.findViewById(R.id.status_message);
this.actionLayout = view.findViewById(R.id.action_layout);
}
}
}

View file

@ -0,0 +1,97 @@
package com.sunilpaulmathew.debloater.adapters;
import android.annotation.SuppressLint;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.AppCompatImageButton;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.textview.MaterialTextView;
import com.sunilpaulmathew.debloater.R;
import com.sunilpaulmathew.debloater.utils.Common;
import com.sunilpaulmathew.debloater.utils.Utils;
import java.util.List;
import in.sunilpaulmathew.sCommon.CommonUtils.sCommonUtils;
import in.sunilpaulmathew.sCommon.ThemeUtils.sThemeUtils;
/*
* Created by sunilpaulmathew <sunil.kde@gmail.com> on February 03, 2021
*/
public class InactivePackagesAdapter extends RecyclerView.Adapter<InactivePackagesAdapter.ViewHolder> {
private final List<String> data;
public InactivePackagesAdapter(List<String> data) {
this.data = data;
}
@NonNull
@Override
public InactivePackagesAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View rowItem = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycle_view_layout, parent, false);
return new InactivePackagesAdapter.ViewHolder(rowItem);
}
@SuppressLint("UseCompatLoadingForDrawables")
@Override
public void onBindViewHolder(@NonNull InactivePackagesAdapter.ViewHolder holder, int position) {
holder.appName.setText(Utils.read(this.data.get(position)));
if (sThemeUtils.isDarkTheme(holder.appName.getContext())) {
holder.appName.setTextColor(Utils.getThemeAccentColor(holder.appName.getContext()));
}
holder.appID.setText(this.data.get(position).replace(Common.getModuleParent(),""));
holder.appIcon.setImageDrawable(sCommonUtils.getDrawable(R.drawable.ic_android, holder.appIcon.getContext()));
holder.appIcon.setColorFilter(Utils.exist(this.data.get(position)) ? Color.RED : Color.GREEN);
holder.statusMessage.setTextColor(Utils.exist(this.data.get(position)) ? Color.RED : Color.GREEN);
holder.actionMessage.setTextColor(Utils.exist(this.data.get(position)) ? Color.GREEN : Color.RED);
holder.actionIcon.setColorFilter(Utils.exist(this.data.get(position)) ? Color.GREEN : Color.RED);
holder.actionMessage.setText(Utils.exist(this.data.get(position)) ? holder.actionMessage.getContext().getString(R.string.restore) : holder.actionMessage.getContext().getString(R.string.remove));
holder.actionIcon.setImageDrawable(Utils.exist(this.data.get(position)) ? sCommonUtils.getDrawable(R.drawable.ic_restore,
holder.actionMessage.getContext()) : sCommonUtils.getDrawable(R.drawable.ic_delete, holder.actionMessage.getContext()));
holder.statusMessage.setText(Utils.exist(this.data.get(position)) ? null : holder.statusMessage.getContext().getString(R.string.status_message_restore));
holder.statusMessage.setVisibility(Utils.exist(this.data.get(position)) ? View.GONE : View.VISIBLE);
holder.actionLayout.setOnClickListener(v -> {
if (Utils.exist(this.data.get(position))) {
Utils.delete(this.data.get(position));
} else {
Utils.create(holder.appName.getText().toString(), this.data.get(position));
}
notifyItemChanged(position);
});
}
@Override
public int getItemCount() {
return this.data.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
private final AppCompatImageButton actionIcon;
private final AppCompatImageButton appIcon;
private final MaterialTextView appName;
private final MaterialTextView appID;
private final MaterialTextView actionMessage;
private final MaterialTextView statusMessage;
private final FrameLayout actionLayout;
public ViewHolder(View view) {
super(view);
this.actionIcon = view.findViewById(R.id.action_icon);
this.appIcon = view.findViewById(R.id.icon);
this.appName = view.findViewById(R.id.title);
this.appID = view.findViewById(R.id.description);
this.actionMessage = view.findViewById(R.id.action_message);
this.statusMessage = view.findViewById(R.id.status_message);
this.actionLayout = view.findViewById(R.id.action_layout);
}
}
}

View file

@ -0,0 +1,81 @@
package com.sunilpaulmathew.debloater.fragments;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.activity.OnBackPressedCallback;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.sunilpaulmathew.debloater.BuildConfig;
import com.sunilpaulmathew.debloater.R;
import com.sunilpaulmathew.debloater.adapters.AboutAdapter;
import com.sunilpaulmathew.debloater.utils.Utils;
import java.util.ArrayList;
import java.util.List;
import in.sunilpaulmathew.sCommon.CommonUtils.sCommonUtils;
import in.sunilpaulmathew.sCommon.CommonUtils.sSerializableItems;
import in.sunilpaulmathew.sCommon.PackageUtils.sPackageUtils;
/*
* Created by sunilpaulmathew <sunil.kde@gmail.com> on October 28, 2020
*/
public class AboutFragment extends Fragment {
@SuppressLint("UseCompatLoadingForDrawables")
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View mRootView = inflater.inflate(R.layout.fragment_about, container, false);
RecyclerView mRecyclerView = mRootView.findViewById(R.id.recycler_view);
mRecyclerView.setLayoutManager(new GridLayoutManager(requireActivity(), Utils.getSpanCount(requireActivity())));
AboutAdapter mRecycleViewAdapter = new AboutAdapter(getData());
mRecyclerView.setAdapter(mRecycleViewAdapter);
mRecyclerView.setVisibility(View.VISIBLE);
requireActivity().getOnBackPressedDispatcher().addCallback(new OnBackPressedCallback(true) {
@Override
public void handleOnBackPressed() {
Utils.navigateToFragment(requireActivity());
}
});
return mRootView;
}
private List<sSerializableItems> getData() {
List <sSerializableItems> mData = new ArrayList<>();
mData.add(new sSerializableItems(sCommonUtils.getDrawable(R.mipmap.ic_launcher_round, requireActivity()), getString(R.string.version).replace(": %s",""), (sPackageUtils.isPackageInstalled(
"com.android.vending", requireActivity()) ? "Pro " : "") + BuildConfig.VERSION_NAME, null));
mData.add(new sSerializableItems(sCommonUtils.getDrawable(R.drawable.ic_support, requireActivity()), getString(R.string.support), getString(R.string.support_summary),"https://t.me/smartpack_kmanager"));
mData.add(new sSerializableItems(sCommonUtils.getDrawable(R.drawable.ic_github, requireActivity()), getString(R.string.source_code), getString(R.string.source_code_summary),"https://github.com/sunilpaulmathew/De-Bloater"));
mData.add(new sSerializableItems(sCommonUtils.getDrawable(R.drawable.ic_issue, requireActivity()), getString(R.string.report_issue), getString(R.string.report_issue_summary),"https://github.com/sunilpaulmathew/De-Bloater/issues/new"));
mData.add(new sSerializableItems(sCommonUtils.getDrawable(R.drawable.ic_active, requireActivity()), getString(R.string.change_logs), getString(R.string.change_logs_summary), null));
mData.add(new sSerializableItems(sCommonUtils.getDrawable(R.drawable.ic_playstore, requireActivity()), getString(R.string.more_apps), getString(R.string.more_apps_summary), "https://play.google.com/store/apps/dev?id=5836199813143882901"));
mData.add(new sSerializableItems(sCommonUtils.getDrawable(R.drawable.ic_licence, requireActivity()), getString(R.string.licence), getString(R.string.licence_summary), "https://www.gnu.org/licenses/gpl-3.0-standalone.html"));
if (sPackageUtils.isPackageInstalled("com.android.vending", requireActivity())) {
mData.add(new sSerializableItems(sCommonUtils.getDrawable(R.drawable.ic_rate, requireActivity()), getString(R.string.rate_us), getString(R.string.rate_us_Summary), "https://play.google.com/store/apps/details?id=com.sunilpaulmathew.debloater"));
} else if (sPackageUtils.isPackageInstalled("org.fdroid.fdroid", requireActivity())) {
mData.add(new sSerializableItems(sCommonUtils.getDrawable(R.drawable.ic_fdroid, requireActivity()), getString(R.string.fdroid), getString(R.string.fdroid_summary), "https://f-droid.org/packages/com.sunilpaulmathew.debloater"));
} else {
mData.add(new sSerializableItems(sCommonUtils.getDrawable(R.drawable.ic_update, requireActivity()),getString(R.string.check_update), getString(R.string.check_update_summary), null));
}
mData.add(new sSerializableItems(sCommonUtils.getDrawable(R.drawable.ic_translate, requireActivity()), getString(R.string.translations), getString(R.string.translations_summary), null));
mData.add(new sSerializableItems(sCommonUtils.getDrawable(R.drawable.ic_credits, requireActivity()), getString(R.string.credits), getString(R.string.credits_summary), null));
mData.add(new sSerializableItems(sCommonUtils.getDrawable(R.drawable.ic_share, requireActivity()), getString(R.string.invite_friend), getString(R.string.invite_friend_summary), null));
if (!sPackageUtils.isPackageInstalled("com.android.vending", requireActivity())) {
mData.add(new sSerializableItems(sCommonUtils.getDrawable(R.drawable.ic_donate, requireActivity()), getString(R.string.donate), getString(R.string.donate_summary), "https://smartpack.github.io/donation/"));
}
return mData;
}
}

View file

@ -0,0 +1,321 @@
package com.sunilpaulmathew.debloater.fragments;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.SubMenu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import androidx.activity.OnBackPressedCallback;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatEditText;
import androidx.appcompat.widget.AppCompatImageButton;
import androidx.appcompat.widget.AppCompatTextView;
import androidx.appcompat.widget.PopupMenu;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.card.MaterialCardView;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.tabs.TabLayout;
import com.google.android.material.textview.MaterialTextView;
import com.sunilpaulmathew.debloater.R;
import com.sunilpaulmathew.debloater.activities.TomatotActivity;
import com.sunilpaulmathew.debloater.activities.UADActivity;
import com.sunilpaulmathew.debloater.adapters.ActivePackagesAdapter;
import com.sunilpaulmathew.debloater.utils.PackageTasks;
import com.sunilpaulmathew.debloater.utils.UpdateCheck;
import com.sunilpaulmathew.debloater.utils.Utils;
import java.util.Objects;
import in.sunilpaulmathew.sCommon.CommonUtils.sCommonUtils;
import in.sunilpaulmathew.sCommon.CommonUtils.sExecutor;
/*
* Created by sunilpaulmathew <sunil.kde@gmail.com> on October 28, 2020
*/
public class ActivePackagesFragment extends Fragment {
private AppCompatEditText mSearchWord;
private AppCompatImageButton mMenu;
private boolean mExit = false;
private final Handler mHandler = new Handler();
private LinearLayout mProgressLayout;
private MaterialCardView mReverse;
private RecyclerView mRecyclerView;
private ActivePackagesAdapter mRecycleViewAdapter;
private String mSearchText = null;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View mRootView = inflater.inflate(R.layout.fragment_packages, container, false);
mSearchWord = mRootView.findViewById(R.id.search_word);
AppCompatImageButton mSearchButton = mRootView.findViewById(R.id.search_button);
AppCompatTextView mSummary = mRootView.findViewById(R.id.about_summary);
MaterialTextView mPageTitle = mRootView.findViewById(R.id.page_title);
mReverse = mRootView.findViewById(R.id.reverse_button);
mMenu = mRootView.findViewById(R.id.menu_button);
mProgressLayout = mRootView.findViewById(R.id.progress_layout);
mRecyclerView = mRootView.findViewById(R.id.recycler_view);
TabLayout mTabLayout = mRootView.findViewById(R.id.tab_layout);
mRecyclerView.setLayoutManager(new LinearLayoutManager(requireActivity()));
mPageTitle.setText(getString(R.string.apps, getString(R.string.active)));
mSummary.setText(getString(R.string.active_app_summary));
mReverse.setElevation(10);
mReverse.setOnClickListener(v -> {
sCommonUtils.saveBoolean("reverse_order", !sCommonUtils.getBoolean("reverse_order", false, requireActivity()), requireActivity());
loadUI(requireActivity(), mSearchText);
});
mSearchButton.setOnClickListener(v -> {
if (mSearchWord.getVisibility() == View.VISIBLE) {
if (mSearchText != null && !mSearchText.isEmpty()) {
mSearchText = null;
mSearchWord.setText(null);
}
mSummary.setVisibility(View.VISIBLE);
mSearchWord.setVisibility(View.GONE);
PackageTasks.toggleKeyboard(mSearchWord, 0, requireActivity());
} else {
mSummary.setVisibility(View.GONE);
mSearchWord.setVisibility(View.VISIBLE);
PackageTasks.toggleKeyboard(mSearchWord, 1, requireActivity());
}
});
mTabLayout.addTab(mTabLayout.newTab().setText(getString(R.string.apps_all)));
mTabLayout.addTab(mTabLayout.newTab().setText(getString(R.string.apps_system)));
mTabLayout.addTab(mTabLayout.newTab().setText(getString(R.string.apps_product)));
mTabLayout.addTab(mTabLayout.newTab().setText(getString(R.string.apps_vendor)));
mTabLayout.setVisibility(View.VISIBLE);
Objects.requireNonNull(mTabLayout.getTabAt(getTabPosition(requireActivity()))).select();
mTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
String mStatus = sCommonUtils.getString("appTypes", "all", requireActivity());
switch (tab.getPosition()) {
case 0:
if (!mStatus.equals("all")) {
sCommonUtils.saveString("appTypes", "all", requireActivity());
loadUI(requireActivity(), mSearchText);
}
break;
case 1:
if (!mStatus.equals("system")) {
sCommonUtils.saveString("appTypes", "system", requireActivity());
loadUI(requireActivity(), mSearchText);
}
break;
case 2:
if (!mStatus.equals("product")) {
sCommonUtils.saveString("appTypes", "product", requireActivity());
loadUI(requireActivity(), mSearchText);
}
break;
case 3:
if (!mStatus.equals("vendor")) {
sCommonUtils.saveString("appTypes", "vendor", requireActivity());
loadUI(requireActivity(), mSearchText);
}
break;
}
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
mSearchWord.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
loadUI(requireActivity(), s.toString().toLowerCase());
}
});
mMenu.setOnClickListener(v -> menuOptions(requireActivity()));
loadUI(requireActivity(), mSearchText);
if (UpdateCheck.isSignatureMatched(requireActivity()) && sCommonUtils.getInt("update_enabled", 2, requireActivity()) == 2) {
new MaterialAlertDialogBuilder(requireActivity())
.setIcon(R.mipmap.ic_launcher_round)
.setTitle("Please Note")
.setMessage("""
De-Bloater includes a built-in auto-update system that is active only when the app is installed via the GitHub release page or through IzzyOnDroid. Updates are fetched directly from the latest official release on GitHub.
You can choose to enable or disable this feature. This prompt will keep appearing until you make a decision.""")
.setCancelable(false)
.setNeutralButton("No, Thanks", (dialogInterface, i) ->
sCommonUtils.saveInt("update_enabled", 1, requireActivity()))
.setPositiveButton("Yes, Enable", (dialogInterface, i) ->
sCommonUtils.saveInt("update_enabled", 0, requireActivity()))
.show();
}
requireActivity().getOnBackPressedDispatcher().addCallback(new OnBackPressedCallback(true) {
@Override
public void handleOnBackPressed() {
if (mSearchWord.getVisibility() == View.VISIBLE) {
if (mSearchText != null) {
mSearchText = null;
mSearchWord.setText(null);
}
mSearchWord.setVisibility(View.GONE);
return;
}
if (mExit) {
mExit = false;
requireActivity().finish();
} else {
sCommonUtils.toast(getString(R.string.press_back_exit), requireActivity()).show();
mExit = true;
mHandler.postDelayed(() -> mExit = false, 2000);
}
}
});
return mRootView;
}
private int getTabPosition(Activity activity) {
String mStatus = sCommonUtils.getString("appTypes", "all", activity);
return switch (mStatus) {
case "vendor" -> 3;
case "product" -> 2;
case "system" -> 1;
default -> 0;
};
}
private void menuOptions(Activity activity) {
PopupMenu popupMenu = new PopupMenu(activity, mMenu);
Menu menu = popupMenu.getMenu();
if (PackageTasks.isModuleInitialized()) {
menu.add(Menu.NONE, 1, Menu.NONE, R.string.module_status_reset);
}
SubMenu sort = menu.addSubMenu(Menu.NONE, 0, Menu.NONE, getString(R.string.sort_by));
sort.add(0, 2, Menu.NONE, getString(R.string.name)).setCheckable(true)
.setChecked(sCommonUtils.getInt("sort_apps", 1, activity) == 0);
sort.add(0, 3, Menu.NONE, getString(R.string.package_id)).setCheckable(true)
.setChecked(sCommonUtils.getInt("sort_apps", 1, activity) == 1);
sort.setGroupCheckable(0, true, true);
SubMenu customScripts = menu.addSubMenu(Menu.NONE, 0, Menu.NONE, getString(R.string.custom_scripts));
customScripts.add(Menu.NONE, 4, Menu.NONE, R.string.custom_scripts_tomatot);
customScripts.add(Menu.NONE, 5, Menu.NONE, R.string.custom_scripts_uad);
menu.add(Menu.NONE, 6, Menu.NONE, R.string.reboot);
popupMenu.setOnMenuItemClickListener(item -> {
switch (item.getItemId()) {
case 0:
break;
case 1:
PackageTasks.removeModule(activity);
break;
case 2:
if (sCommonUtils.getInt("sort_apps", 1, activity) != 0) {
sCommonUtils.saveInt("sort_apps", 0, activity);
loadUI(activity, mSearchText);
}
break;
case 3:
if (sCommonUtils.getInt("sort_apps", 1, activity) != 1) {
sCommonUtils.saveInt("sort_apps", 1, activity);
loadUI(activity, mSearchText);
}
break;
case 4:
Intent tomatotScript = new Intent(activity, TomatotActivity.class);
startActivity(tomatotScript);
break;
case 5:
Intent uadScript = new Intent(activity, UADActivity.class);
startActivity(uadScript);
break;
case 6:
Utils.runCommand("svc power reboot");
break;
}
return false;
});
popupMenu.show();
}
private void loadUI(Activity activity, String searchText) {
new sExecutor() {
@Override
public void onPreExecute() {
mProgressLayout.setVisibility(View.VISIBLE);
mReverse.setVisibility(View.GONE);
mRecyclerView.setVisibility(View.GONE);
mRecyclerView.removeAllViews();
}
@Override
public void doInBackground() {
mRecycleViewAdapter = new ActivePackagesAdapter(PackageTasks.getActivePackageData(activity, searchText), searchText);
if (searchText != null) {
mSearchText = searchText;
}
}
@Override
public void onPostExecute() {
mRecyclerView.setAdapter(mRecycleViewAdapter);
mProgressLayout.setVisibility(View.GONE);
mRecyclerView.setVisibility(View.VISIBLE);
mReverse.setVisibility(View.VISIBLE);
}
}.execute();
}
@Override
public void onStart() {
super.onStart();
if (mSearchText != null) {
mSearchText = null;
mSearchWord.setText(null);
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (mSearchText != null) {
mSearchText = null;
mSearchWord.setText(null);
}
}
}

View file

@ -0,0 +1,313 @@
package com.sunilpaulmathew.debloater.fragments;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import androidx.activity.OnBackPressedCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatEditText;
import androidx.appcompat.widget.AppCompatImageButton;
import androidx.appcompat.widget.AppCompatTextView;
import androidx.appcompat.widget.PopupMenu;
import androidx.core.content.FileProvider;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.textview.MaterialTextView;
import com.sunilpaulmathew.debloater.BuildConfig;
import com.sunilpaulmathew.debloater.R;
import com.sunilpaulmathew.debloater.adapters.InactivePackagesAdapter;
import com.sunilpaulmathew.debloater.utils.EditTextInterface;
import com.sunilpaulmathew.debloater.utils.PackageTasks;
import com.sunilpaulmathew.debloater.utils.Restore;
import com.sunilpaulmathew.debloater.utils.Utils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.File;
import in.sunilpaulmathew.rootfilepicker.utils.FilePicker;
import in.sunilpaulmathew.sCommon.CommonUtils.sCommonUtils;
import in.sunilpaulmathew.sCommon.CommonUtils.sExecutor;
/*
* Created by sunilpaulmathew <sunil.kde@gmail.com> on October 28, 2020
*/
public class InactivePackagesFragment extends Fragment {
private AppCompatEditText mSearchWord;
private AppCompatImageButton mMenu;
private LinearLayout mProgressLayout;
private MaterialTextView mProgressText;
private RecyclerView mRecyclerView;
private InactivePackagesAdapter mRecycleViewAdapter;
private String mSearchText = null;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View mRootView = inflater.inflate(R.layout.fragment_packages, container, false);
mSearchWord = mRootView.findViewById(R.id.search_word);
AppCompatTextView mSummary = mRootView.findViewById(R.id.about_summary);
mProgressLayout = mRootView.findViewById(R.id.progress_layout);
mProgressText = mRootView.findViewById(R.id.progress_text);
mRecyclerView = mRootView.findViewById(R.id.recycler_view);
mRecyclerView = mRootView.findViewById(R.id.recycler_view);
mRecyclerView.setLayoutManager(new LinearLayoutManager(requireActivity()));
MaterialTextView mTitle = mRootView.findViewById(R.id.page_title);
AppCompatImageButton mSearchButton = mRootView.findViewById(R.id.search_button);
mMenu = mRootView.findViewById(R.id.menu_button);
mTitle.setText(getString(R.string.apps, getString(R.string.inactive)));
mSummary.setText(getString(R.string.inactive_apps_summary));
mMenu.setOnClickListener(v -> menuOptions(requireActivity()));
loadUI(mSearchText);
mSearchButton.setOnClickListener(v -> {
if (mSearchWord.getVisibility() == View.VISIBLE) {
if (mSearchText != null && !mSearchText.isEmpty()) {
mSearchText = null;
mSearchWord.setText(null);
}
mSummary.setVisibility(View.VISIBLE);
mSearchWord.setVisibility(View.GONE);
PackageTasks.toggleKeyboard(mSearchWord, 0, requireActivity());
} else {
mSummary.setVisibility(View.GONE);
mSearchWord.setVisibility(View.VISIBLE);
PackageTasks.toggleKeyboard(mSearchWord, 1, requireActivity());
}
});
mSearchWord.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
loadUI(s.toString().toLowerCase());
}
});
requireActivity().getOnBackPressedDispatcher().addCallback(new OnBackPressedCallback(true) {
@Override
public void handleOnBackPressed() {
if (mSearchWord.getVisibility() == View.VISIBLE) {
if (mSearchText != null) {
mSearchText = null;
mSearchWord.setText(null);
}
mSummary.setVisibility(View.VISIBLE);
mSearchWord.setVisibility(View.GONE);
return;
}
Utils.navigateToFragment(requireActivity());
}
});
return mRootView;
}
private void menuOptions(Activity activity) {
PopupMenu popupMenu = new PopupMenu(activity, mMenu);
Menu menu = popupMenu.getMenu();
if (PackageTasks.isModuleInitialized()) {
menu.add(Menu.NONE, 0, Menu.NONE, R.string.module_status_reset);
}
menu.add(Menu.NONE, 1, Menu.NONE, R.string.reboot);
menu.add(Menu.NONE, 2, Menu.NONE, R.string.backup);
menu.add(Menu.NONE, 3, Menu.NONE, R.string.restore);
popupMenu.setOnMenuItemClickListener(item -> {
switch (item.getItemId()) {
case 0:
PackageTasks.removeModule(activity);
loadUI(mSearchText);
break;
case 1:
Utils.runCommand("svc power reboot");
break;
case 2:
if (!PackageTasks.getInactivePackageData(null).isEmpty()) {
new EditTextInterface(Build.MODEL.replace(" ","_")
.replace("(","_").replace(")","_") + "_" +
Build.VERSION.SDK_INT, getString(R.string.backup_list_as), activity) {
@SuppressLint("StringFormatInvalid")
@Override
public void positiveButtonLister(Editable editable) {
String name = editable.toString().trim().replace(" ","_")
.replace("(","_").replace(")","_");
if (!name.endsWith(".json")) {
name = name + ".json";
}
File jsonFile = new File(PackageTasks.getStoragePath(), name);
try {
JSONObject obj = new JSONObject();
JSONObject device = new JSONObject();
JSONArray DeBloater = new JSONArray();
device.put("Manufacturer", Build.MANUFACTURER);
device.put("Brand", Build.BRAND);
device.put("Model", Build.MODEL);
device.put("Version", Build.VERSION.RELEASE);
device.put("SDK", Build.VERSION.SDK_INT);
obj.put("Device", device);
for (String s : PackageTasks.getInactivePackageData(null)) {
JSONObject app = new JSONObject();
app.put("name", Utils.read(s));
app.put("path", s);
DeBloater.put(app);
obj.put("DeBloater", DeBloater);
}
Utils.create(obj.toString(), jsonFile.getAbsolutePath());
new MaterialAlertDialogBuilder(requireActivity())
.setIcon(R.mipmap.ic_launcher)
.setTitle(R.string.app_name)
.setMessage(getString(R.string.backup_message, jsonFile.getAbsolutePath()) + "\n\n" + getString(R.string.backup_share_message))
.setNegativeButton(getString(R.string.cancel), (dialogInterface, i) -> {
})
.setPositiveButton(getString(R.string.share_profile), (dialogInterface, i) -> {
Uri uriFile = FileProvider.getUriForFile(activity,
BuildConfig.APPLICATION_ID + ".provider", jsonFile);
Intent share = new Intent(Intent.ACTION_SEND);
share.setType("*/*");
share.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.app_name));
share.putExtra(Intent.EXTRA_TEXT, "De-Bloater profile for " + Build.MODEL + " (SDK: " + Build.VERSION.SDK_INT + ").");
share.putExtra(Intent.EXTRA_STREAM, uriFile);
share.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Intent shareIntent = Intent.createChooser(share, null);
startActivity(shareIntent);
}).show();
} catch (JSONException ignored) {
}
}
}.show();
} else {
sCommonUtils.snackBar(mRecyclerView, getString(R.string.backup_list_empty)).show();
}
break;
case 3:
FilePicker filePicker = new FilePicker(restoreResultLauncher, requireActivity());
filePicker.setPath(Environment.getExternalStorageDirectory().toString());
filePicker.setExtension("json");
filePicker.launch();
break;
}
return false;
});
popupMenu.show();
}
private void loadUI(String searchText) {
new sExecutor() {
@Override
public void onPreExecute() {
mProgressLayout.setVisibility(View.VISIBLE);
mRecyclerView.setVisibility(View.GONE);
mRecyclerView.removeAllViews();
}
@Override
public void doInBackground() {
mRecycleViewAdapter = new InactivePackagesAdapter(PackageTasks.getInactivePackageData(searchText));
if (searchText != null) {
mSearchText = searchText;
}
}
@Override
public void onPostExecute() {
mRecyclerView.setAdapter(mRecycleViewAdapter);
mProgressLayout.setVisibility(View.GONE);
mRecyclerView.setVisibility(View.VISIBLE);
}
}.execute();
}
@SuppressLint("StringFormatInvalid")
private final ActivityResultLauncher<Intent> restoreResultLauncher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) {
File mSelectedFile = FilePicker.getSelectedFile();
if (!Restore.isValidBackup(mSelectedFile.getAbsolutePath())) {
sCommonUtils.snackBar(mRecyclerView, getString(R.string.restore_error_message)).show();
return;
}
new MaterialAlertDialogBuilder(requireActivity())
.setMessage(Restore.isJSONMatched(mSelectedFile.getAbsolutePath()) ? getString(R.string.restore_question,
mSelectedFile.getName()) : getString(R.string.restore_mismatch_message))
.setNegativeButton(getString(R.string.cancel), (dialogInterface, i) -> {
})
.setPositiveButton(getString(R.string.restore), (dialogInterface, i) ->
new sExecutor() {
@Override
public void onPreExecute() {
mProgressLayout.setVisibility(View.VISIBLE);
mProgressText.setText(getString(R.string.restoring));
}
@Override
public void doInBackground() {
Restore.restoreBackup(mSelectedFile.getAbsolutePath());
}
@Override
public void onPostExecute() {
mProgressLayout.setVisibility(View.GONE);
loadUI(mSearchText);
}
}.execute())
.show();
}
}
);
@Override
public void onStart() {
super.onStart();
if (mSearchText != null) {
mSearchText = null;
mSearchWord.setText(null);
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (mSearchText != null) {
mSearchText = null;
mSearchWord.setText(null);
}
}
}

View file

@ -0,0 +1,209 @@
package com.sunilpaulmathew.debloater.fragments;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatImageButton;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.card.MaterialCardView;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.textview.MaterialTextView;
import com.sunilpaulmathew.debloater.R;
import com.sunilpaulmathew.debloater.adapters.ActivePackagesAdapter;
import com.sunilpaulmathew.debloater.utils.Common;
import com.sunilpaulmathew.debloater.utils.Tomatot;
import com.sunilpaulmathew.debloater.utils.Utils;
import in.sunilpaulmathew.sCommon.CommonUtils.sCommonUtils;
import in.sunilpaulmathew.sCommon.CommonUtils.sExecutor;
import in.sunilpaulmathew.sCommon.ThemeUtils.sThemeUtils;
/*
* Created by sunilpaulmathew <sunil.kde@gmail.com> on November 4, 2020
*/
public class TomatotDebloaterFragment extends Fragment {
private boolean mExtremeT = false, mInvisibleT = false, mLightT = false;
private MaterialCardView mAppListCard;
private LinearLayout mProgressLayout;
private RecyclerView mRecyclerView;
private ActivePackagesAdapter mRecycleViewAdapter;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View mRootView = inflater.inflate(R.layout.fragment_tomatot_debloater, container, false);
AppCompatImageButton mActionIcon = mRootView.findViewById(R.id.action_icon);
mProgressLayout = mRootView.findViewById(R.id.progress_layout);
LinearLayout mTitleLayout = mRootView.findViewById(R.id.title_layout);
MaterialTextView mInvisible = mRootView.findViewById(R.id.invisible);
MaterialTextView mLight = mRootView.findViewById(R.id.light);
MaterialTextView mExtreme = mRootView.findViewById(R.id.extreme);
MaterialTextView mStatus = mRootView.findViewById(R.id.deblaoter_status);
MaterialTextView mActionMessage = mRootView.findViewById(R.id.action_message);
mRecyclerView = mRootView.findViewById(R.id.recycler_view);
mRecyclerView.setLayoutManager(new LinearLayoutManager(requireActivity()));
MaterialTextView mAppsListTitle = mRootView.findViewById(R.id.apps_list_title);
mAppListCard = mRootView.findViewById(R.id.apps_list_card);
FrameLayout mActionLayout = mRootView.findViewById(R.id.action_layout);
if (sThemeUtils.isDarkTheme(requireActivity())) {
mActionMessage.setTextColor(Utils.getThemeAccentColor(requireActivity()));
mActionIcon.setColorFilter(Utils.getThemeAccentColor(requireActivity()));
mAppsListTitle.setTextColor(Utils.getThemeAccentColor(requireActivity()));
}
if (Tomatot.isScriptEnabled("tomatot_extreme", requireActivity())) {
mInvisible.setTextColor(Utils.getPrimaryTextColor(requireActivity()));
mLight.setTextColor(Utils.getPrimaryTextColor(requireActivity()));
mExtreme.setTextColor(Utils.getThemeAccentColor(requireActivity()));
mStatus.setText(R.string.custom_scripts_uad_enabled);
mActionMessage.setText(R.string.restore);
mExtremeT = true;
mRecycleViewAdapter = new ActivePackagesAdapter(Common.getTExtreme(), null);
mRecyclerView.setAdapter(mRecycleViewAdapter);
mAppListCard.setVisibility(View.VISIBLE);
} else if (Tomatot.isScriptEnabled("tomatot_light", requireActivity())) {
mInvisible.setTextColor(Utils.getPrimaryTextColor(requireActivity()));
mLight.setTextColor(Utils.getThemeAccentColor(requireActivity()));
mExtreme.setTextColor(Utils.getPrimaryTextColor(requireActivity()));
mStatus.setText(R.string.custom_scripts_uad_enabled);
mActionMessage.setText(R.string.restore);
mLightT = true;
mRecycleViewAdapter = new ActivePackagesAdapter(Common.getTLight(), null);
mRecyclerView.setAdapter(mRecycleViewAdapter);
mAppListCard.setVisibility(View.VISIBLE);
} else {
mInvisible.setTextColor(Utils.getThemeAccentColor(requireActivity()));
mLight.setTextColor(Utils.getPrimaryTextColor(requireActivity()));
mExtreme.setTextColor(Utils.getPrimaryTextColor(requireActivity()));
mStatus.setText(sCommonUtils.getBoolean("tomatot_invisible", false, requireActivity()) ?
R.string.custom_scripts_uad_enabled : R.string.custom_scripts_tomatot_invisible);
mActionMessage.setText(sCommonUtils.getBoolean("tomatot_invisible", false, requireActivity()) ?
R.string.restore : R.string.apply);
mInvisibleT = true;
mRecycleViewAdapter = new ActivePackagesAdapter(Common.geTInvisible(), null);
mRecyclerView.setAdapter(mRecycleViewAdapter);
mAppListCard.setVisibility(View.VISIBLE);
}
mTitleLayout.setOnClickListener(v -> sCommonUtils.launchUrl("https://forum.xda-developers.com" +
"/oneplus-6/oneplus-6--6t-cross-device-development/tool-tomatot-debloater-basic-script-to-t3869427",
requireActivity()));
mInvisible.setOnClickListener(v -> {
mExtremeT = false;
mInvisibleT = true;
mLightT = false;
mInvisible.setTextColor(Utils.getThemeAccentColor(requireActivity()));
mLight.setTextColor(Utils.getPrimaryTextColor(requireActivity()));
mExtreme.setTextColor(Utils.getPrimaryTextColor(requireActivity()));
mStatus.setText(sCommonUtils.getBoolean("tomatot_invisible", false, requireActivity()) ?
R.string.custom_scripts_uad_enabled : R.string.custom_scripts_tomatot_invisible);
mActionMessage.setText(sCommonUtils.getBoolean("tomatot_invisible", false, requireActivity()) ?
R.string.restore : R.string.apply);
mRecycleViewAdapter = new ActivePackagesAdapter(Common.geTInvisible(), null);
mRecyclerView.setAdapter(mRecycleViewAdapter);
});
mLight.setOnClickListener(v -> {
mExtremeT = false;
mInvisibleT = false;
mLightT = true;
mInvisible.setTextColor(Utils.getPrimaryTextColor(requireActivity()));
mLight.setTextColor(Utils.getThemeAccentColor(requireActivity()));
mExtreme.setTextColor(Utils.getPrimaryTextColor(requireActivity()));
mStatus.setText(sCommonUtils.getBoolean("tomatot_light", false, requireActivity()) ?
R.string.custom_scripts_uad_enabled : R.string.custom_scripts_tomatot_light);
mActionMessage.setText(sCommonUtils.getBoolean("tomatot_light", false, requireActivity()) ?
R.string.restore : R.string.apply);
mRecycleViewAdapter = new ActivePackagesAdapter(Common.getTLight(), null);
mRecyclerView.setAdapter(mRecycleViewAdapter);
});
mExtreme.setOnClickListener(v -> {
mExtremeT = true;
mInvisibleT = false;
mLightT = false;
mInvisible.setTextColor(Utils.getPrimaryTextColor(requireActivity()));
mLight.setTextColor(Utils.getPrimaryTextColor(requireActivity()));
mExtreme.setTextColor(Utils.getThemeAccentColor(requireActivity()));
mStatus.setText(sCommonUtils.getBoolean("tomatot_extreme", false, requireActivity()) ?
R.string.custom_scripts_uad_enabled : R.string.custom_scripts_tomatot_extreme);
mActionMessage.setText(sCommonUtils.getBoolean("tomatot_extreme", false, requireActivity()) ?
R.string.restore : R.string.apply);
mRecycleViewAdapter = new ActivePackagesAdapter(Common.getTExtreme(), null);
mRecyclerView.setAdapter(mRecycleViewAdapter);
});
mActionLayout.setOnClickListener(v ->
new sExecutor() {
@Override
public void onPreExecute() {
mProgressLayout.setVisibility(View.VISIBLE);
mAppListCard.setVisibility(View.GONE);
}
@Override
public void doInBackground() {
if (mExtremeT) {
if (sCommonUtils.getBoolean("tomatot_extreme", false, requireActivity())) {
Tomatot.disable("tomatot_extreme", Common.getTExtreme(), requireActivity());
} else {
if (Tomatot.isScriptEnabled("tomatot_invisible", requireActivity())) {
Tomatot.disable("tomatot_invisible", Common.geTInvisible(), requireActivity());
}
if (Tomatot.isScriptEnabled("tomatot_light", requireActivity())) {
Tomatot.disable("tomatot_light", Common.getTLight(), requireActivity());
}
Tomatot.enable("tomatot_extreme", Common.getTExtreme(), requireActivity());
}
} else if (mInvisibleT) {
if (sCommonUtils.getBoolean("tomatot_invisible", false, requireActivity())) {
Tomatot.disable("tomatot_invisible", Common.geTInvisible(), requireActivity());
} else {
if (Tomatot.isScriptEnabled("tomatot_light", requireActivity())) {
Tomatot.disable("tomatot_light", Common.getTLight(), requireActivity());
}
if (Tomatot.isScriptEnabled("tomatot_extreme", requireActivity())) {
Tomatot.disable("tomatot_extreme", Common.getTExtreme(), requireActivity());
}
Tomatot.enable("tomatot_invisible", Common.geTInvisible(), requireActivity());
}
} else if (mLightT) {
if (sCommonUtils.getBoolean("tomatot_light", false, requireActivity())) {
Tomatot.disable("tomatot_light", Common.getTLight(), requireActivity());
} else {
if (Tomatot.isScriptEnabled("tomatot_invisible", requireActivity())) {
Tomatot.disable("tomatot_invisible", Common.geTInvisible(), requireActivity());
}
if (Tomatot.isScriptEnabled("tomatot_extreme", requireActivity())) {
Tomatot.disable("tomatot_extreme", Common.getTExtreme(), requireActivity());
}
Tomatot.enable("tomatot_light", Common.getTLight(), requireActivity());
}
}
}
@Override
public void onPostExecute() {
mProgressLayout.setVisibility(View.GONE);
new MaterialAlertDialogBuilder(requireActivity())
.setMessage(R.string.custom_scripts_applied_message)
.setCancelable(false)
.setPositiveButton(getString(R.string.cancel), (dialog, id) -> requireActivity().finish()).show();
}
}.execute()
);
return mRootView;
}
}

View file

@ -0,0 +1,331 @@
package com.sunilpaulmathew.debloater.fragments;
import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatImageButton;
import androidx.appcompat.widget.PopupMenu;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.card.MaterialCardView;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.textview.MaterialTextView;
import com.sunilpaulmathew.debloater.R;
import com.sunilpaulmathew.debloater.adapters.ActivePackagesAdapter;
import com.sunilpaulmathew.debloater.utils.Common;
import com.sunilpaulmathew.debloater.utils.PackageTasks;
import com.sunilpaulmathew.debloater.utils.UAD;
import com.sunilpaulmathew.debloater.utils.Utils;
import in.sunilpaulmathew.sCommon.CommonUtils.sCommonUtils;
import in.sunilpaulmathew.sCommon.CommonUtils.sExecutor;
import in.sunilpaulmathew.sCommon.ThemeUtils.sThemeUtils;
/*
* Created by sunilpaulmathew <sunil.kde@gmail.com> on January 26, 2021
*/
public class UADFragment extends Fragment {
private AppCompatImageButton mSelectIcon;
private MaterialCardView mAppListCard;
private MaterialTextView mActionMessage, mScriptTitle, mScriptStatus;
private LinearLayout mProgressLayout;
private RecyclerView mRecyclerView;
private ActivePackagesAdapter mRecycleViewAdapter;
private String mScriptPath;
private String mTitle;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View mRootView = inflater.inflate(R.layout.fragment_uad, container, false);
AppCompatImageButton mActionIcon = mRootView.findViewById(R.id.action_icon);
mSelectIcon = mRootView.findViewById(R.id.select_icon);
FrameLayout mActionLayout = mRootView.findViewById(R.id.action_layout);
mProgressLayout = mRootView.findViewById(R.id.progress_layout);
LinearLayout mTitleLayout = mRootView.findViewById(R.id.title_layout);
mAppListCard = mRootView.findViewById(R.id.apps_list_card);
mActionMessage = mRootView.findViewById(R.id.action_message);
MaterialTextView mAppsListTitle = mRootView.findViewById(R.id.apps_list_title);
mScriptTitle = mRootView.findViewById(R.id.script_title);
mScriptStatus = mRootView.findViewById(R.id.deblaoter_status);
mRecyclerView = mRootView.findViewById(R.id.recycler_view);
mRecyclerView.setLayoutManager(new LinearLayoutManager(requireActivity()));
if (sThemeUtils.isDarkTheme(requireActivity())) {
mActionMessage.setTextColor(Utils.getThemeAccentColor(requireActivity()));
mActionIcon.setColorFilter(Utils.getThemeAccentColor(requireActivity()));
mAppsListTitle.setTextColor(Utils.getThemeAccentColor(requireActivity()));
mScriptTitle.setTextColor(Utils.getThemeAccentColor(requireActivity()));
}
if (Build.BRAND.equalsIgnoreCase("oneplus")) {
mScriptPath = PackageTasks.getModulePath() + "/uad_oneplus";
mRecycleViewAdapter = new ActivePackagesAdapter(Common.getOnePlus(), null);
mTitle = getString(R.string.oneplus);
} else if (Build.BRAND.equalsIgnoreCase("asus")) {
mScriptPath = PackageTasks.getModulePath() + "/uad_asus";
mRecycleViewAdapter = new ActivePackagesAdapter(Common.getAsus(), null);
mTitle = getString(R.string.asus);
} else if (Build.BRAND.equalsIgnoreCase("motorola")) {
mScriptPath = PackageTasks.getModulePath() + "/uad_motorola";
mRecycleViewAdapter = new ActivePackagesAdapter(Common.getMoto(), null);
mTitle = getString(R.string.motorola);
} else if (Build.BRAND.equalsIgnoreCase("huawei")) {
mScriptPath = PackageTasks.getModulePath() + "/uad_huawei";
mRecycleViewAdapter = new ActivePackagesAdapter(Common.getHuawei(), null);
mTitle = getString(R.string.huawei);
} else if (Build.BRAND.equalsIgnoreCase("lg")) {
mScriptPath = PackageTasks.getModulePath() + "/uad_lg";
mRecycleViewAdapter = new ActivePackagesAdapter(Common.getLG(), null);
mTitle = getString(R.string.lg);
} else if (Build.BRAND.equalsIgnoreCase("samsung")) {
mScriptPath = PackageTasks.getModulePath() + "/uad_samsung";
mRecycleViewAdapter = new ActivePackagesAdapter(Common.getSamsung(), null);
mTitle = getString(R.string.samsung);
} else if (Build.BRAND.equalsIgnoreCase("nokia")) {
mScriptPath = PackageTasks.getModulePath() + "/uad_nokia";
mRecycleViewAdapter = new ActivePackagesAdapter(Common.getNokia(), null);
mTitle = getString(R.string.nokia);
} else if (Build.BRAND.equalsIgnoreCase("oppo")) {
mScriptPath = PackageTasks.getModulePath() + "/uad_oppo";
mRecycleViewAdapter = new ActivePackagesAdapter(Common.getOppo(), null);
mTitle = getString(R.string.oppo);
} else if (Build.BRAND.equalsIgnoreCase("sony")) {
mScriptPath = PackageTasks.getModulePath() + "/uad_sony";
mRecycleViewAdapter = new ActivePackagesAdapter(Common.getSony(), null);
mTitle = getString(R.string.sony);
} else if (Build.BRAND.equalsIgnoreCase("xiaomi")) {
mScriptPath = PackageTasks.getModulePath() + "/uad_xiaomi";
mRecycleViewAdapter = new ActivePackagesAdapter(Common.getXiaomi(), null);
mTitle = getString(R.string.xiaomi);
} else if (Build.BRAND.equalsIgnoreCase("zte")) {
mScriptPath = PackageTasks.getModulePath() + "/uad_zte";
mRecycleViewAdapter = new ActivePackagesAdapter(Common.getZTE(), null);
mTitle = getString(R.string.zte);
} else {
mScriptPath = PackageTasks.getModulePath() + "/uad_google";
mRecycleViewAdapter = new ActivePackagesAdapter(Common.getGoogle(), null);
mTitle = getString(R.string.google);
}
setStatus();
mTitleLayout.setOnClickListener(v -> sCommonUtils.launchUrl( "https://gitlab.com/W1nst0n/universal-android-debloater",
requireActivity()));
mActionLayout.setOnClickListener(v ->
new sExecutor() {
@Override
public void onPreExecute() {
mProgressLayout.setVisibility(View.VISIBLE);
mAppListCard.setVisibility(View.GONE);
}
@Override
public void doInBackground() {
UAD.applyScript(mScriptPath, requireActivity());
}
@Override
public void onPostExecute() {
mProgressLayout.setVisibility(View.GONE);
new MaterialAlertDialogBuilder(requireActivity())
.setMessage(R.string.custom_scripts_applied_message)
.setCancelable(false)
.setPositiveButton(getString(R.string.cancel), (dialog, id) -> requireActivity().finish()).show();
}
}.execute()
);
mSelectIcon.setOnClickListener(v -> selectionMenu(requireActivity()));
return mRootView;
}
private void selectionMenu(Activity activity) {
PopupMenu popupMenu = new PopupMenu(requireActivity(), mSelectIcon);
Menu menu = popupMenu.getMenu();
if (!Common.getAOSP().isEmpty() || Utils.exist("uad_aosp")) {
menu.add(Menu.NONE, 0, Menu.NONE, R.string.aosp);
}
if (!Common.getGoogle().isEmpty() || Utils.exist("uad_google")) {
menu.add(Menu.NONE, 1, Menu.NONE, R.string.google);
}
if (!Common.getOnePlus().isEmpty() || Utils.exist("uad_oneplus")) {
menu.add(Menu.NONE, 2, Menu.NONE, R.string.oneplus);
}
if (!Common.getAsus().isEmpty() || Utils.exist("uad_asus")) {
menu.add(Menu.NONE, 3, Menu.NONE, R.string.asus);
}
if (!Common.getHuawei().isEmpty() || Utils.exist("uad_huawei")) {
menu.add(Menu.NONE, 4, Menu.NONE, R.string.huawei);
}
if (!Common.getLG().isEmpty() || Utils.exist("uad_lg")) {
menu.add(Menu.NONE, 5, Menu.NONE, R.string.lg);
}
if (!Common.getSamsung().isEmpty() || Utils.exist("uad_samsung")) {
menu.add(Menu.NONE, 6, Menu.NONE, R.string.samsung);
}
if (!Common.getMoto().isEmpty() || Utils.exist("uad_motorola")) {
menu.add(Menu.NONE, 7, Menu.NONE, R.string.motorola);
}
if (!Common.getNokia().isEmpty() || Utils.exist("uad_nokia")) {
menu.add(Menu.NONE, 8, Menu.NONE, R.string.nokia);
}
if (!Common.getOppo().isEmpty() || Utils.exist("uad_oppo")) {
menu.add(Menu.NONE, 9, Menu.NONE, R.string.oppo);
}
if (!Common.getSony().isEmpty() || Utils.exist("uad_sony")) {
menu.add(Menu.NONE, 10, Menu.NONE, R.string.sony);
}
if (!Common.getXiaomi().isEmpty() || Utils.exist("uad_xiaomi")) {
menu.add(Menu.NONE, 11, Menu.NONE, R.string.xiaomi);
}
if (!Common.getZTE().isEmpty() || Utils.exist("uad_zte")) {
menu.add(Menu.NONE, 12, Menu.NONE, R.string.zte);
}
if (!Common.getCarrier().isEmpty() || Utils.exist("uad_carrier")) {
menu.add(Menu.NONE, 13, Menu.NONE, R.string.carrier);
}
if (!Common.getMisc().isEmpty() || Utils.exist("uad_misc")) {
menu.add(Menu.NONE, 14, Menu.NONE, R.string.miscellaneous);
}
popupMenu.setOnMenuItemClickListener(item -> {
switch (item.getItemId()) {
case 0:
sCommonUtils.saveString("setDefault", "aosp", activity);
mScriptPath = PackageTasks.getModulePath() + "/uad_aosp";
mRecycleViewAdapter = new ActivePackagesAdapter(Common.getAOSP(), null);
mTitle = getString(R.string.aosp);
setStatus();
break;
case 1:
sCommonUtils.saveString("setDefault", "google", activity);
mScriptPath = PackageTasks.getModulePath() + "/uad_google";
mRecycleViewAdapter = new ActivePackagesAdapter(Common.getGoogle(), null);
mTitle = getString(R.string.google);
setStatus();
break;
case 2:
sCommonUtils.saveString("setDefault", "oneplus", activity);
mScriptPath = PackageTasks.getModulePath() + "/uad_oneplus";
mRecycleViewAdapter = new ActivePackagesAdapter(Common.getOnePlus(), null);
mTitle = getString(R.string.oneplus);
setStatus();
break;
case 3:
sCommonUtils.saveString("setDefault", "asus", activity);
mScriptPath = PackageTasks.getModulePath() + "/uad_aosp";
mRecycleViewAdapter = new ActivePackagesAdapter(Common.getAsus(), null);
mTitle = getString(R.string.asus);
setStatus();
break;
case 4:
sCommonUtils.saveString("setDefault", "huawei", activity);
mScriptPath = PackageTasks.getModulePath() + "/uad_huawei";
mRecycleViewAdapter = new ActivePackagesAdapter(Common.getHuawei(), null);
mTitle = getString(R.string.huawei);
setStatus();
break;
case 5:
sCommonUtils.saveString("setDefault", "lg", activity);
mScriptPath = PackageTasks.getModulePath() + "/uad_lg";
mRecycleViewAdapter = new ActivePackagesAdapter(Common.getLG(), null);
mTitle = getString(R.string.lg);
setStatus();
break;
case 6:
sCommonUtils.saveString("setDefault", "samsung", activity);
mScriptPath = PackageTasks.getModulePath() + "/uad_samsung";
mRecycleViewAdapter = new ActivePackagesAdapter(Common.getSamsung(), null);
mTitle = getString(R.string.samsung);
setStatus();
break;
case 7:
sCommonUtils.saveString("setDefault", "motorola", activity);
mScriptPath = PackageTasks.getModulePath() + "/uad_motorola";
mRecycleViewAdapter = new ActivePackagesAdapter(Common.getMoto(), null);
mTitle = getString(R.string.motorola);
setStatus();
break;
case 8:
sCommonUtils.saveString("setDefault", "nokia", activity);
mScriptPath = PackageTasks.getModulePath() + "/uad_nokia";
mRecycleViewAdapter = new ActivePackagesAdapter(Common.getNokia(), null);
mTitle = getString(R.string.nokia);
setStatus();
break;
case 9:
sCommonUtils.saveString("setDefault", "oppo", activity);
mScriptPath = PackageTasks.getModulePath() + "/uad_oppo";
mRecycleViewAdapter = new ActivePackagesAdapter(Common.getOppo(), null);
mTitle = getString(R.string.oppo);
setStatus();
break;
case 10:
sCommonUtils.saveString("setDefault", "sony", activity);
mScriptPath = PackageTasks.getModulePath() + "/uad_sony";
mRecycleViewAdapter = new ActivePackagesAdapter(Common.getSony(), null);
mTitle = getString(R.string.sony);
setStatus();
break;
case 11:
sCommonUtils.saveString("setDefault", "xiaomi", activity);
mScriptPath = PackageTasks.getModulePath() + "/uad_xiaomi";
mRecycleViewAdapter = new ActivePackagesAdapter(Common.getXiaomi(), null);
mTitle = getString(R.string.xiaomi);
setStatus();
break;
case 12:
sCommonUtils.saveString("setDefault", "zte", activity);
mScriptPath = PackageTasks.getModulePath() + "/uad_zte";
mRecycleViewAdapter = new ActivePackagesAdapter(Common.getZTE(), null);
mTitle = getString(R.string.zte);
setStatus();
break;
case 13:
sCommonUtils.saveString("setDefault", "carrier", activity);
mScriptPath = PackageTasks.getModulePath() + "/uad_carrier";
mRecycleViewAdapter = new ActivePackagesAdapter(Common.getCarrier(), null);
mTitle = getString(R.string.carrier);
setStatus();
break;
case 14:
sCommonUtils.saveString("setDefault", "misc", activity);
mScriptPath = PackageTasks.getModulePath() + "/uad_misc";
mRecycleViewAdapter = new ActivePackagesAdapter(Common.getMisc(), null);
mTitle = getString(R.string.miscellaneous);
setStatus();
break;
}
return false;
});
popupMenu.show();
}
private void setStatus() {
if (Utils.exist(mScriptPath)) {
mScriptStatus.setText(getString(R.string.custom_scripts_uad_enabled));
} else {
mScriptStatus.setText(getString(R.string.custom_scripts_uad_disabled));
}
mActionMessage.setText(Utils.exist(mScriptPath) ? getString(R.string.restore) : getString(R.string.apply));
mScriptTitle.setText(mTitle);
mRecyclerView.setAdapter(mRecycleViewAdapter);
}
}

View file

@ -0,0 +1,157 @@
package com.sunilpaulmathew.debloater.utils;
/*
* Created by sunilpaulmathew <sunil.kde@gmail.com> on June 10, 2021
*/
import android.content.Context;
import java.util.ArrayList;
import java.util.List;
import in.sunilpaulmathew.sCommon.CommonUtils.sSerializableItems;
public class Common {
private static List<PackageItem> mRawData;
private static final List<PackageItem> mAOSP = new ArrayList<>(), mAsus = new ArrayList<>(),
mCarrier = new ArrayList<>(), mGoogle = new ArrayList<>(), mHuawei = new ArrayList<>(),
mLG = new ArrayList<>(), mSamsung = new ArrayList<>(), mMisc = new ArrayList<>(),
mMoto = new ArrayList<>(), mNokia = new ArrayList<>(), mOnePlus = new ArrayList<>(),
mOppo = new ArrayList<>(), mSony = new ArrayList<>(), mTInvisible = new ArrayList<>(),
mTLight = new ArrayList<>(), mTExtreme = new ArrayList<>(), mXiaomi = new ArrayList<>(),
mZTE = new ArrayList<>();
public static boolean isTextMatched(String searchText, String searchWord) {
for (int a = 0; a < searchText.length() - searchWord.length() + 1; a++) {
if (searchWord.equalsIgnoreCase(searchText.substring(a, a + searchWord.length()))) {
return true;
}
}
return false;
}
public static List<PackageItem> getAOSP() {
return mAOSP;
}
public static List<PackageItem> getAsus() {
return mAsus;
}
public static List<PackageItem> getCarrier() {
return mCarrier;
}
public static List<PackageItem> getGoogle() {
return mGoogle;
}
public static List<PackageItem> getHuawei() {
return mHuawei;
}
public static List<PackageItem> getLG() {
return mLG;
}
public static List<PackageItem> getMisc() {
return mMisc;
}
public static List<PackageItem> getMoto() {
return mMoto;
}
public static List<PackageItem> getNokia() {
return mNokia;
}
public static List<PackageItem> getOppo() {
return mOppo;
}
public static List<PackageItem> getOnePlus() {
return mOnePlus;
}
public static List<PackageItem> getRawData() {
return mRawData;
}
public static List<PackageItem> getSamsung() {
return mSamsung;
}
public static List<PackageItem> getSony() {
return mSony;
}
public static List<PackageItem> geTInvisible() {
return mTInvisible;
}
public static List<PackageItem> getTLight() {
return mTLight;
}
public static List<PackageItem> getTExtreme() {
return mTExtreme;
}
public static List<PackageItem> getXiaomi() {
return mXiaomi;
}
public static List<PackageItem> getZTE() {
return mZTE;
}
public static List<sSerializableItems> getCredits() {
List<sSerializableItems> mData = new ArrayList<>();
mData.add(new sSerializableItems(null, "Willi Ye", "Kernel Adiutor", "https://github.com/Grarak/KernelAdiutor"));
mData.add(new sSerializableItems(null, "John Wu", "libsu & Magisk", "https://github.com/topjohnwu"));
mData.add(new sSerializableItems(null, "weishu", "KernelSU", "https://github.com/tiann"));
mData.add(new sSerializableItems(null, "Nikita", "Russian & Ukrainian Translations", "https://t.me/MONSTER_PC"));
mData.add(new sSerializableItems(null, "Emre", "Turkish Translations", "https://t.me/xcooLwastaken"));
mData.add(new sSerializableItems(null, "Firerust96", "Spanish Translations", "https://github.com/Firerust96"));
mData.add(new sSerializableItems(null, "lay4play", "Italian Translations", null));
mData.add(new sSerializableItems(null, "Axel Schaab", "German Translations", null));
mData.add(new sSerializableItems(null, "alex", "Polish Translations", null));
mData.add(new sSerializableItems(null, "Ktosspl", "Polish Translations", null));
mData.add(new sSerializableItems(null, "Valdnet", "Polish Translations", "https://github.com/Valdnet"));
mData.add(new sSerializableItems(null, "Reno", "French Translations", null));
mData.add(new sSerializableItems(null, "Ebolateam", "French Translations", null));
mData.add(new sSerializableItems(null, "Hoa Gia Đại Thiếu", "Vietnamese Translations", null));
mData.add(new sSerializableItems(null, "ひきたり", "Vietnamese Translations", null));
mData.add(new sSerializableItems(null, "qiaoxin", "Chinese - Hong Kong (Traditional and Simplified) Translations", null));
mData.add(new sSerializableItems(null, "MMETMA", "Arabic Translations", "https://github.com/MMETMA"));
mData.add(new sSerializableItems(null, "Guima Teixeira", "French (Belgian)", null));
mData.add(new sSerializableItems(null, "蔡承佑", "Chinese (Traditional) Translations", null));
mData.add(new sSerializableItems(null, "Geovanni", "Portuguese (Brazilian) Translations", null));
mData.add(new sSerializableItems(null, "Chong", "Chinese (Simplified) Translations", null));
mData.add(new sSerializableItems(null, "Lw201811", "Japanese & Chinese (Simplified) Translations", null));
mData.add(new sSerializableItems(null, "Hongle", "Chinese - Hong Kong (Traditional and Simplified) Translations", null));
mData.add(new sSerializableItems(null, "Ignác Czébán", "Hungarian Translations", null));
mData.add(new sSerializableItems(null, "mx. sony", "Slovakian Translations", null));
mData.add(new sSerializableItems(null, "Leudy R. Villa Calcaño", "Dominican Spanish Translations", null));
mData.add(new sSerializableItems(null, "Many other volunteers", "Contributed via. POEditor", "https://poeditor.com/join/project?hash=BZS89Ev3WG"));
return mData;
}
public static String getModuleParent() {
return "/data/adb/modules/De-bloater";
}
public static String geLatestAPK(Context context) {
return context.getExternalFilesDir("") + "/app-release.apk";
}
public static String getLatestVersionUrl() {
return "https://raw.githubusercontent.com/sunilpaulmathew/De-Bloater/master/app/src/main/assets/release.json";
}
public static void setRawData(List<PackageItem> rawData) {
mRawData = rawData;
}
}

View file

@ -0,0 +1,64 @@
package com.sunilpaulmathew.debloater.utils;
import android.content.Context;
import android.text.Editable;
import android.view.Gravity;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import androidx.appcompat.widget.AppCompatEditText;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.sunilpaulmathew.debloater.R;
/*
* Created by sunilpaulmathew <sunil.kde@gmail.com> on February 04, 2023
*/
public abstract class EditTextInterface {
private final Context mContext;
private final MaterialAlertDialogBuilder mDialogBuilder;
private final String mText, mTitle;
public EditTextInterface(String text, String title, Context context) {
this.mText = text;
this.mTitle = title;
this.mContext = context;
this.mDialogBuilder = new MaterialAlertDialogBuilder(context);
}
private void startDialog() {
LinearLayout layout = new LinearLayout(mContext);
layout.setPadding(75, 75, 75, 75);
final AppCompatEditText editText = new AppCompatEditText(mContext);
editText.setGravity(Gravity.CENTER);
editText.setLayoutParams(new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
if (mText != null) {
editText.append(mText);
}
editText.setSingleLine(true);
editText.requestFocus();
layout.addView(editText);
if (mTitle != null) {
mDialogBuilder.setTitle(mTitle);
mDialogBuilder.setIcon(R.mipmap.ic_launcher);
}
mDialogBuilder.setView(layout);
mDialogBuilder.setIcon(R.mipmap.ic_launcher);
mDialogBuilder.setNegativeButton(R.string.cancel, (dialog, id) -> {
});
mDialogBuilder.setPositiveButton(R.string.backup, (dialog, id) ->
positiveButtonLister(editText.getText())
).show();
}
public void show() {
startDialog();
}
public abstract void positiveButtonLister(Editable s);
}

View file

@ -0,0 +1,45 @@
package com.sunilpaulmathew.debloater.utils;
import android.graphics.drawable.Drawable;
import java.io.Serializable;
/*
* Created by sunilpaulmathew <sunil.kde@gmail.com> on February 03, 2021
*/
public class PackageItem implements Serializable {
private final String mAppName, mAPKPath, mPackageName;
private final Drawable mAppIcon;
private final boolean mUpdatedSystemApp;
public PackageItem(String appName, String apkPath, Drawable appIcon, String packageName, boolean updatedSystemApp) {
this.mAppName = appName;
this.mAPKPath = apkPath;
this.mAppIcon = appIcon;
this.mPackageName = packageName;
this.mUpdatedSystemApp = updatedSystemApp;
}
public String getAppName() {
return mAppName;
}
public String getAPKPath() {
return mAPKPath;
}
public Drawable getAppIcon() {
return mAppIcon;
}
public String getPackageName() {
return mPackageName;
}
public boolean isUpdatedSystemApp() {
return mUpdatedSystemApp;
}
}

View file

@ -0,0 +1,193 @@
package com.sunilpaulmathew.debloater.utils;
import android.app.Activity;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Environment;
import android.view.inputmethod.InputMethodManager;
import androidx.appcompat.widget.AppCompatEditText;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import in.sunilpaulmathew.sCommon.APKUtils.sAPKUtils;
import in.sunilpaulmathew.sCommon.CommonUtils.sCommonUtils;
import in.sunilpaulmathew.sCommon.PackageUtils.sPackageUtils;
/*
* Created by sunilpaulmathew <sunil.kde@gmail.com> on October 27, 2020
*/
public class PackageTasks {
static void createModuleParent() {
Utils.runCommand(Utils.magiskBusyBox() + "mkdir " + Common.getModuleParent());
}
public static List<PackageItem> getRawData(Context context) {
List<PackageItem> mData = new ArrayList<>();
List<ApplicationInfo> packages = getPackageManager(context).getInstalledApplications(PackageManager.GET_META_DATA);
for (ApplicationInfo packageInfo: packages) {
if ((packageInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
mData.add(new PackageItem(
sPackageUtils.getAppName(packageInfo.packageName, context).toString(),
sPackageUtils.isUpdatedSystemApp(packageInfo.packageName, context) ? findSystemAPKPath(packageInfo.packageName,
context) : sPackageUtils.getSourceDir(packageInfo.packageName, context),
sPackageUtils.getAppIcon(packageInfo.packageName, context),
packageInfo.packageName,
sPackageUtils.isUpdatedSystemApp(packageInfo.packageName, context)));
}
}
return mData;
}
public static List<PackageItem> getActivePackageData(Context context, String searchText) {
List<PackageItem> mData = new ArrayList<>();
for (PackageItem item : Common.getRawData()) {
if (getSupportedAppsList(item.getAPKPath(), context)) {
if (searchText == null) {
mData.add(item);
} else if (Common.isTextMatched(item.getAppName(), searchText) || Common.isTextMatched(item.getPackageName(), searchText)) {
mData.add(item);
}
}
}
if (sCommonUtils.getInt("sort_apps", 1, context) == 0) {
Collections.sort(mData, (lhs, rhs) -> String.CASE_INSENSITIVE_ORDER.compare(lhs.getAppName(), rhs.getAppName()));
} else {
Collections.sort(mData, (lhs, rhs) -> String.CASE_INSENSITIVE_ORDER.compare(lhs.getPackageName(), rhs.getPackageName()));
}
if (sCommonUtils.getBoolean("reverse_order", false, context)) {
Collections.reverse(mData);
}
return mData;
}
public static List<String> getInactivePackageData(String searchText) {
List<String> mData = new ArrayList<>();
for (String line : Utils.runAndGetOutput(Utils.magiskBusyBox() + "find " + Common.getModuleParent() + "/system -type f -name *.apk").split("\\r?\\n")) {
if (line.endsWith(".apk")) {
if (searchText == null) {
mData.add(line);
} else if (Common.isTextMatched(line, searchText)) {
mData.add(line);
}
}
}
return mData;
}
private static boolean getSupportedAppsList(String apkPath, Context context) {
String mStatus = sCommonUtils.getString("appTypes", "all", context);
boolean systemApps = apkPath.startsWith("/system/app") || apkPath.startsWith("/system/priv-app")
|| apkPath.startsWith("/system/product/app") || apkPath.startsWith("/system/product/priv-app")
|| apkPath.startsWith("/system/vendor/app") || apkPath.startsWith("/system/vendor/overlay")
|| apkPath.startsWith("/system/product/overlay") || apkPath.startsWith("/system/system_ext/app")
|| apkPath.startsWith("/system/system_ext/priv-app") || apkPath.startsWith("/system_ext/app")
|| apkPath.startsWith("/system_ext/priv-app") || apkPath.startsWith("/system/preload");
boolean vendorApps = apkPath.startsWith("/vendor/overlay") || apkPath.startsWith("/vendor/app");
boolean productApps = apkPath.startsWith("/product/app") || apkPath.startsWith("/product/priv-app")
|| apkPath.startsWith("/product/overlay");
return switch (mStatus) {
case "system" -> systemApps;
case "product" -> productApps;
case "vendor" -> vendorApps;
default -> true;
};
}
public static PackageManager getPackageManager(Context context) {
return context.getPackageManager();
}
public static String findSystemAPKPath(String packageName, Context context) {
try {
String mAPKPath = null;
for (String line : Utils.runAndGetOutput("dumpsys package " + packageName + " | grep resourcePath").replace("resourcePath=", "").split("\\r?\\n")) {
if (!line.startsWith("/data/")) {
mAPKPath = line.replaceAll("\\s+", "");
for (File mFile : Objects.requireNonNull(new File(mAPKPath).listFiles())) {
if (Objects.equals(sAPKUtils.getPackageName(mFile.getAbsolutePath(), context), packageName)) {
mAPKPath = mAPKPath + File.separator + mFile.getName();
}
}
}
}
if (Utils.exist(mAPKPath)) return mAPKPath;
} catch (NullPointerException ignored) {}
return sPackageUtils.getSourceDir(packageName, context);
}
public static String getAdjAPKPath(String apkPath) {
if (apkPath.startsWith("/product/")) {
apkPath = apkPath.replace("/product", "/system/product");
} else if (apkPath.startsWith("/vendor/")) {
apkPath = apkPath.replace("/vendor", "/system/vendor");
} else if (apkPath.startsWith("/system_ext/")) {
apkPath = apkPath.replace("/system_ext", "/system/system_ext");
}
return apkPath;
}
public static String getStoragePath() {
return Environment.getExternalStorageDirectory().getPath();
}
public static String getModulePath() {
return Common.getModuleParent();
}
public static void initializeModule() {
if (!Utils.exist(Common.getModuleParent())) {
createModuleParent();
Utils.chmod("755", Common.getModuleParent());
Utils.create("id=De-bloater\n" +
"name=De-bloater\n" +
"version=v1.0\n" +
"versionCode=1\n" +
"author=sunilpaulmathew\n" +
"description=De-bloat apps Systemless-ly",
Common.getModuleParent() + "/module.prop");
Utils.chmod("644", Common.getModuleParent() + "/module.prop");
}
}
public static void removeModule(Activity activity) {
Utils.delete(activity.getFilesDir().getPath() + "/De-bloater");
Utils.delete(Common.getModuleParent());
sCommonUtils.saveBoolean("tomatot_extreme", false, activity);
sCommonUtils.saveBoolean("tomatot_invisible", false, activity);
sCommonUtils.saveBoolean("tomatot_light", false, activity);
}
public static boolean isModuleInitialized() {
return Utils.exist(Common.getModuleParent()) && Utils.exist(Common.getModuleParent() + "/module.prop");
}
public static void setToDelete(String path, String name) {
initializeModule();
Utils.runCommand(Utils.magiskBusyBox() + " mkdir -p " + Common.getModuleParent() + new File(path).getParentFile());
Utils.create(name, Common.getModuleParent() + path);
}
public static void revertDelete(String path) {
Utils.delete(Common.getModuleParent() + path);
}
public static void toggleKeyboard(AppCompatEditText editText, int mode, Context context) {
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
if (mode == 1) {
if (editText.requestFocus()) {
imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT);
}
} else {
imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
}
}
}

View file

@ -0,0 +1,71 @@
package com.sunilpaulmathew.debloater.utils;
import android.os.Build;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import in.sunilpaulmathew.sCommon.JsonUtils.sJSONUtils;
/*
* Created by sunilpaulmathew <sunil.kde@gmail.com> on November 17, 2020
*/
public class Restore {
private static JSONArray getAppList(String json) {
return sJSONUtils.getJSONArray(sJSONUtils.getJSONObject(json), "DeBloater");
}
private static JSONObject getDeviceInfo(String json) {
return sJSONUtils.getJSONObject(sJSONUtils.getString(sJSONUtils.getJSONObject(json), "Device"));
}
private static String getName(String string) {
return sJSONUtils.getString(sJSONUtils.getJSONObject(string), "name");
}
private static String getModel(String string) {
return sJSONUtils.getString(sJSONUtils.getJSONObject(string), "Model");
}
private static int getSDK(String string) {
return sJSONUtils.getInt(sJSONUtils.getJSONObject(string), "SDK");
}
private static String getPath(String string) {
return sJSONUtils.getString(sJSONUtils.getJSONObject(string), "path");
}
public static boolean isValidBackup(String path) {
return getAppList(Utils.read(path)) != null;
}
public static boolean isJSONMatched(String path) {
if (getDeviceInfo(Utils.read(path)) == null) return true;
return Objects.equals(getModel(Utils.read(path)), Build.MODEL) && getSDK(Utils.read(path)) == Build.VERSION.SDK_INT;
}
public static void restoreBackup(String path) {
List<String> mRestoreData = new ArrayList<>();
if (Utils.exist(path)) {
for (int i = 0; i < Objects.requireNonNull(getAppList(Utils.read(path))).length(); i++) {
try {
mRestoreData.add(Objects.requireNonNull(getAppList(Utils.read(path))).getJSONObject(i).toString());
} catch (JSONException ignored) {
}
}
}
for (String s : mRestoreData) {
if (Utils.exist(Objects.requireNonNull(getPath(s)).replace("/data/adb/modules/De-bloater",""))) {
PackageTasks.setToDelete(Objects.requireNonNull(getPath(s)).replace("/data/adb/modules/De-bloater",""), getName(s));
}
}
}
}

View file

@ -0,0 +1,243 @@
package com.sunilpaulmathew.debloater.utils;
import android.content.Context;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import in.sunilpaulmathew.sCommon.APKUtils.sAPKUtils;
import in.sunilpaulmathew.sCommon.CommonUtils.sCommonUtils;
/*
* Created by sunilpaulmathew <sunil.kde@gmail.com> on November 03, 2020
*/
public class Tomatot {
public static List<String> getTomatotInvisible() {
List<String> mData = new ArrayList<>();
mData.add("/system/app/AntHalService/AntHalService.apk");
mData.add("/system/app/AutoRegistration/AutoRegistration.apk");
mData.add("/system/app/BasicDreams/BasicDreams.apk");
mData.add("/system/app/BookmarkProvider/BookmarkProvider.apk");
mData.add("/system/app/BTtestmode/BTtestmode.apk");
mData.add("/system/app/BuiltInPrintService/BuiltInPrintService.apk");
mData.add("/system/app/card/card.apk");
mData.add("/system/app/CtsShimPrebuilt/CtsShimPrebuilt.apk");
mData.add("/system/app/EasterEgg_O2/EasterEgg_O2.apk");
mData.add("/system/app/EngineeringMode/EngineeringMode.apk");
mData.add("/system/app/EngSpecialTest/EngSpecialTest.apk");
mData.add("/system/app/GooglePrintRecommendationService/GooglePrintRecommendationService.apk");
mData.add("/system/app/GoogleTTS/GoogleTTS.apk");
mData.add("/system/app/LogKitSdService/LogKitSdService.apk");
mData.add("/system/app/NFCTestMode/NFCTestMode.apk");
mData.add("/system/app/OEMLogKit/OEMLogKit.apk");
mData.add("/system/app/oem_tcma/oem_tcma.apk");
mData.add("/system/app/OPBugReportLite/OPBugReportLite.apk");
mData.add("/system/app/OPCommonLogTool/OPCommonLogTool.apk");
mData.add("/system/app/OPLiveWallpaper/OPLiveWallpaper.apk");
mData.add("/system/app/OPPush/OPPush.apk");
mData.add("/system/app/PartnerBookmarksProvider/PartnerBookmarksProvider.apk");
mData.add("/system/app/PhotosOnline/PhotosOnline.apk");
mData.add("/system/app/PlayAutoInstallConfig/PlayAutoInstallConfig.apk");
mData.add("/system/app/RFTuner/RFTuner.apk");
mData.add("/system/app/SensorTestTool/SensorTestTool.apk");
mData.add("/system/app/SoterService/SoterService.apk");
mData.add("/system/app/Stk/Stk.apk");
mData.add("/system/app/SeempService/SeempService.apk");
mData.add("/system/app/talkback/talkback.apk");
mData.add("/system/app/Traceur/Traceur.apk");
mData.add("/system/app/WallpaperBackup/WallpaperBackup.apk");
mData.add("/system/app/WapiCertManage/WapiCertManage.apk");
mData.add("/system/app/WifiRfTestApk/WifiRfTestApk.apk");
mData.add("/system/priv-app/CtsShimPrivPrebuilt/CtsShimPrivPrebuilt.apk");
mData.add("/system/priv-app/OPCellBroadcastReceiver/OPCellBroadcastReceiver.apk");
mData.add("/system/priv-app/TagGoogle/TagGoogle.apk");
mData.add("/system/product/app/uimremoteclient/uimremoteclient.apk");
mData.add("/system/product/priv-app/GoogleFeedback/GoogleFeedback.apk");
mData.add("/product/app/uimremoteclient/uimremoteclient.apk");
mData.add("/product/priv-app/GoogleFeedback/GoogleFeedback.apk");
mData.add("/system/etc/usb_drivers.iso/usb_drivers.iso.apk");
return mData;
}
public static List<String> getTomatotLight() {
List<String> mData = new ArrayList<>();
mData.add("/system/app/ARCore_stub/ARCore_stub.apk");
mData.add("/system/app/BackupRestoreRemoteService/BackupRestoreRemoteService.apk");
mData.add("/system/app/DiracManager/DiracManager.apk");
mData.add("/system/app/GooglePay/GooglePay.apk");
mData.add("/system/app/HTMLViewer/HTMLViewer.apk");
mData.add("/system/app/NVBackupUI/NVBackupUI.apk");
mData.add("/system/app/OPScreenRecord/OPScreenRecord.apk");
mData.add("/system/priv-app/BackupRestoreConfirmation/BackupRestoreConfirmation.apk");
mData.add("/system/priv-app/CallLogBackup/CallLogBackup.apk");
mData.add("/system/priv-app/DiracAudioControlService/DiracAudioControlService.apk");
mData.add("/system/priv-app/ManagedProvisioning/ManagedProvisioning.apk");
mData.add("/system/priv-app/OnePlusWizard/OnePlusWizard.apk");
mData.add("/system/priv-app/OPDeviceManager/OPDeviceManager.apk");
mData.add("/system/priv-app/OPDeviceManagerProvider/OPDeviceManagerProvider.apk");
mData.add("/system/priv-app/SharedStorageBackup/SharedStorageBackup.apk");
mData.add("/system/product/app/Account/Account.apk");
mData.add("/system/product/app/atfwd/atfwd.apk");
mData.add("/system/product/app/CalendarGoogle/CalendarGoogle.apk");
mData.add("/system/product/app/Chrome/Chrome.apk");
mData.add("/system/product/app/Drive/Drive.apk");
mData.add("/system/product/app/Duo/Duo.apk");
mData.add("/system/product/app/Gmail2/Gmail2.apk");
mData.add("/system/product/app/Music2/Music2.apk");
mData.add("/system/product/app/PhotoTable/PhotoTable.apk");
mData.add("/system/product/app/QdcmFF/QdcmFF.apk");
mData.add("/system/product/app/Videos/Videos.apk");
mData.add("/system/product/app/YouTube/YouTube.apk");
mData.add("/system/product/priv-app/AndroidAutoStub/AndroidAutoStub.apk");
mData.add("/system/product/priv-app/GoogleOneTimeInitializer/GoogleOneTimeInitializer.apk");
mData.add("/system/product/priv-app/SetupWizard/SetupWizard.apk");
mData.add("/system/product/priv-app/Turbo/Turbo.apk");
mData.add("/product/app/Account/Account.apk");
mData.add("/product/app/atfwd/atfwd.apk");
mData.add("/product/app/CalendarGoogle/CalendarGoogle.apk");
mData.add("/product/app/Chrome/Chrome.apk");
mData.add("/product/app/Drive/Drive.apk");
mData.add("/product/app/Duo/Duo.apk");
mData.add("/product/app/Gmail2/Gmail2.apk");
mData.add("/product/app/Music2/Music2.apk");
mData.add("/product/app/PhotoTable/PhotoTable.apk");
mData.add("/product/app/QdcmFF/QdcmFF.apk");
mData.add("/product/app/Videos/Videos.apk");
mData.add("/product/app/YouTube/YouTube.apk");
mData.add("/product/priv-app/AndroidAutoStub/AndroidAutoStub.apk");
mData.add("/product/priv-app/GoogleOneTimeInitializer/GoogleOneTimeInitializer.apk");
mData.add("/product/priv-app/SetupWizard/SetupWizard.apk");
mData.add("/product/priv-app/Turbo/Turbo.apk");
return mData;
}
public static List<String> getTomatotExtreme() {
List<String> mData = new ArrayList<>();
mData.add("/system/app/Backup.apk");
mData.add("/system/app/BluetoothMidiService/BluetoothMidiService.apk");
mData.add("/system/app/LiveWallpapersPicker/LiveWallpapersPicker.apk");
mData.add("/system/app/OPBackup/OPBackup.apk");
mData.add("/system/app/OPBreathMode/OPBreathMode.apk");
mData.add("/system/app/OPSafe/OPSafe.apk");
mData.add("/system/app/OPYellowpage/OPYellowpage.apk");
mData.add("/system/app/WAPPushManager/WAPPushManager.apk");
mData.add("/system/priv-app/EmergencyInfo/EmergencyInfo.apk");
mData.add("/system/priv-app/HotwordEnrollmentOKGoogleWCD9340/HotwordEnrollmentOKGoogleWCD9340.apk");
mData.add("/system/priv-app/HotwordEnrollmentXGoogleWCD9340/HotwordEnrollmentXGoogleWCD9340.apk");
mData.add("/system/priv-app/IFAAService/IFAAService.apk");
mData.add("/system/priv-app/MusicFX/MusicFX.apk");
mData.add("/system/priv-app/OnePlusGallery/OnePlusGallery.apk");
mData.add("/system/priv-app/OPAod/OPAod.apk");
mData.add("/system/priv-app/OPFaceUnlock/OPFaceUnlock.apk");
mData.add("/system/priv-app/ProxyHandler/ProxyHandler.apk");
mData.add("/system/priv-app/VpnDialogs/VpnDialogs.apk");
mData.add("/system/product/app/datastatusnotification/datastatusnotification.apk");
mData.add("/system/product/app/GoogleContactsSyncAdapter/GoogleContactsSyncAdapter.apk");
mData.add("/system/product/app/GoogleLocationHistory/GoogleLocationHistory.apk");
mData.add("/system/product/app/Maps/Maps.apk");
mData.add("/system/product/app/Photos/Photos.apk");
mData.add("/system/product/app/remoteSimLockAuthentication/remoteSimLockAuthentication.apk");
mData.add("/system/product/app/remotesimlockservice/remotesimlockservice.apk");
mData.add("/system/product/app/WebViewGoogle/WebViewGoogle.apk");
mData.add("/system/product/priv-app/OPAppLocker/OPAppLocker.apk");
mData.add("/system/product/priv-app/Velvet/Velvet/Velvet.apk");
mData.add("/system/product/priv-app/WallpaperCropper/WallpaperCropper.apk");
mData.add("/system/product/priv-app/Wellbeing/Wellbeing.apk");
mData.add("/product/app/datastatusnotification/datastatusnotification.apk");
mData.add("/product/app/GoogleContactsSyncAdapter/GoogleContactsSyncAdapter.apk");
mData.add("/product/app/GoogleLocationHistory/GoogleLocationHistory.apk");
mData.add("/product/app/Maps/Maps.apk");
mData.add("/product/app/Photos/Photos.apk");
mData.add("/product/app/remoteSimLockAuthentication/remoteSimLockAuthentication.apk");
mData.add("/product/app/remotesimlockservice/remotesimlockservice.apk");
mData.add("/product/app/WebViewGoogle/WebViewGoogle.apk");
mData.add("/product/priv-app/OPAppLocker/OPAppLocker.apk");
mData.add("/product/priv-app/Velvet/Velvet/Velvet.apk");
mData.add("/product/priv-app/WallpaperCropper/WallpaperCropper.apk");
mData.add("/product/priv-app/Wellbeing/Wellbeing.apk");
return mData;
}
public static void enable(String tag, List<PackageItem> items, Context context) {
PackageTasks.initializeModule();
for (PackageItem item : items) {
if (Utils.exist(item.getAPKPath())) {
PackageTasks.setToDelete(item.getAPKPath(), new File(item.getAPKPath()).getName());
}
}
sCommonUtils.saveBoolean(tag, true, context);
}
public static void disable(String tag, List<PackageItem> items, Context context) {
for (PackageItem item : items) {
if (Utils.exist(PackageTasks.getModulePath() + item.getAPKPath())) {
PackageTasks.revertDelete(item.getAPKPath());
}
}
sCommonUtils.saveBoolean(tag, false, context);
}
public static boolean isScriptEnabled(String tag, Context context) {
return sCommonUtils.getBoolean(tag, false, context);
}
public static void setInvisibleData(Context context) {
try {
for (String path : getTomatotInvisible()) {
if (Utils.exist(path)) {
Common.geTInvisible().add(new PackageItem(Objects.requireNonNull(sAPKUtils.getAPKName(path, context)).toString(),
path, sAPKUtils.getAPKIcon(path, context), sAPKUtils.getPackageName(path, context), false));
}
}
} catch (NullPointerException ignored) {}
}
public static void setLightData(Context context) {
try {
List<PackageItem> items = new ArrayList<>();
for (String path : getTomatotInvisible()) {
if (Utils.exist(path)) {
items.add(new PackageItem(Objects.requireNonNull(sAPKUtils.getAPKName(path, context)).toString(),
path, sAPKUtils.getAPKIcon(path, context), sAPKUtils.getPackageName(path, context), false));
}
}
for (String path : getTomatotLight()) {
if (Utils.exist(path)) {
items.add(new PackageItem(Objects.requireNonNull(sAPKUtils.getAPKName(path, context)).toString(),
path, sAPKUtils.getAPKIcon(path, context), sAPKUtils.getPackageName(path, context), false));
}
}
Common.getTLight().addAll(items);
} catch (NullPointerException ignored) {}
}
public static void setExtremeData(Context context) {
try {
List<PackageItem> items = new ArrayList<>();
for (String path : getTomatotInvisible()) {
if (Utils.exist(path)) {
items.add(new PackageItem(Objects.requireNonNull(sAPKUtils.getAPKName(path, context)).toString(),
path, sAPKUtils.getAPKIcon(path, context), sAPKUtils.getPackageName(path, context), false));
}
}
for (String path : getTomatotLight()) {
if (Utils.exist(path)) {
items.add(new PackageItem(Objects.requireNonNull(sAPKUtils.getAPKName(path, context)).toString(),
path, sAPKUtils.getAPKIcon(path, context), sAPKUtils.getPackageName(path, context), false));
}
}
for (String path : getTomatotExtreme()) {
if (Utils.exist(path)) {
items.add(new PackageItem(Objects.requireNonNull(sAPKUtils.getAPKName(path, context)).toString(),
path, sAPKUtils.getAPKIcon(path, context), sAPKUtils.getPackageName(path, context), false));
}
}
Common.getTExtreme().addAll(items);
} catch (NullPointerException ignored) {}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,265 @@
package com.sunilpaulmathew.debloater.utils;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.preference.PreferenceManager;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.sunilpaulmathew.debloater.BuildConfig;
import com.sunilpaulmathew.debloater.R;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Objects;
import in.sunilpaulmathew.sCommon.CommonUtils.sCommonUtils;
import in.sunilpaulmathew.sCommon.CommonUtils.sExecutor;
import in.sunilpaulmathew.sCommon.JsonUtils.sJSONUtils;
import in.sunilpaulmathew.sCommon.PermissionUtils.sPermissionUtils;
/*
* Created by sunilpaulmathew <sunil.kde@gmail.com> on October 31, 2020
*/
public class UpdateCheck {
private static boolean mManualUpdate = false;
private static int mVersionCode = 0;
private static JSONObject mJSONObject = null;
private static String mChangeLog = null, mSHA1 = null, mReleaseURL = null, mVersionName = null;
public UpdateCheck() {
}
private static boolean isManualUpdate() {
return mManualUpdate;
}
/*
* Based on the ApkSignatureVerifier.java in https://github.com/f-droid/fdroidclient
* Ref: https://raw.githubusercontent.com/f-droid/fdroidclient/master/app/src/main/java/org/fdroid/fdroid/installer/ApkSignatureVerifier.java
*/
public static boolean isSignatureMatched(Context context) {
String mSmartPackKey = "[48, -126, 3, -69, 48, -126, 2, -93, -96, 3, 2, 1, 2, 2, 4, 83, 28, 18, 69, 48, 13, 6, 9, 42, -122, 72, -122, -9, 13, 1, 1, 11, 5, 0, 48, -127, -115, 49, 14, 48, 12, 6, 3, 85, 4, 6, 19, 5, 73, 110, 100, 105, 97, 49, 15, 48, 13, 6, 3, 85, 4, 8, 19, 6, 75, 101, 114, 97, 108, 97, 49, 14, 48, 12, 6, 3, 85, 4, 7, 19, 5, 75, 111, 99, 104, 105, 49, 18, 48, 16, 6, 3, 85, 4, 10, 19, 9, 83, 109, 97, 114, 116, 80, 97, 99, 107, 49, 33, 48, 31, 6, 3, 85, 4, 11, 19, 24, 83, 109, 97, 114, 116, 80, 97, 99, 107, 45, 75, 101, 114, 110, 101, 108, 32, 109, 97, 110, 97, 103, 101, 114, 49, 35, 48, 33, 6, 3, 85, 4, 3, 19, 26, 83, 117, 110, 105, 32, 80, 97, 117, 108, 32, 77, 97, 116, 104, 101, 119, 32, 77, 101, 110, 97, 99, 104, 101, 114, 121, 48, 30, 23, 13, 49, 55, 49, 48, 50, 54, 49, 49, 49, 57, 50, 48, 90, 23, 13, 52, 50, 49, 48, 50, 48, 49, 49, 49, 57, 50, 48, 90, 48, -127, -115, 49, 14, 48, 12, 6, 3, 85, 4, 6, 19, 5, 73, 110, 100, 105, 97, 49, 15, 48, 13, 6, 3, 85, 4, 8, 19, 6, 75, 101, 114, 97, 108, 97, 49, 14, 48, 12, 6, 3, 85, 4, 7, 19, 5, 75, 111, 99, 104, 105, 49, 18, 48, 16, 6, 3, 85, 4, 10, 19, 9, 83, 109, 97, 114, 116, 80, 97, 99, 107, 49, 33, 48, 31, 6, 3, 85, 4, 11, 19, 24, 83, 109, 97, 114, 116, 80, 97, 99, 107, 45, 75, 101, 114, 110, 101, 108, 32, 109, 97, 110, 97, 103, 101, 114, 49, 35, 48, 33, 6, 3, 85, 4, 3, 19, 26, 83, 117, 110, 105, 32, 80, 97, 117, 108, 32, 77, 97, 116, 104, 101, 119, 32, 77, 101, 110, 97, 99, 104, 101, 114, 121, 48, -126, 1, 34, 48, 13, 6, 9, 42, -122, 72, -122, -9, 13, 1, 1, 1, 5, 0, 3, -126, 1, 15, 0, 48, -126, 1, 10, 2, -126, 1, 1, 0, -93, -67, -12, 34, 23, -76, 100, -49, 117, 10, 42, 53, -19, 54, 110, -24, -109, 107, -128, -75, 80, 58, 56, 97, -65, 3, -98, -69, 111, 104, 23, 13, -40, 1, -42, 54, -1, 77, 125, 93, 85, 14, -118, -35, -71, 5, 123, -69, 23, -102, 9, -40, 52, -38, -24, -5, 85, 101, -112, -98, -71, 97, -84, -66, 76, 52, 86, 78, -55, -113, -40, 108, 110, 32, 106, -69, -107, 91, -18, -7, 59, -94, -37, -68, 97, 70, -5, 48, -22, -8, 113, 107, 96, -124, 127, 13, -61, -122, -45, -89, 3, -55, 41, -7, -89, -61, 11, -36, 9, -11, -111, -105, -5, -7, -115, 41, -67, 68, 55, 107, -19, 115, -92, -74, -116, -64, 11, -112, -75, -104, 95, 79, -106, -105, 16, 2, -79, 87, 70, 115, 73, -126, -15, 127, -92, 123, -83, -23, -107, -24, -36, -68, 6, 99, 107, -105, -1, 16, 99, 113, -82, 95, -47, 6, -95, -8, -18, -40, -104, 22, 21, 104, -26, -103, 97, 97, -19, -93, -103, -63, 61, 71, -103, -92, 95, -42, -118, 2, -99, 37, -15, -120, -84, 1, 69, -65, 6, -82, 70, -62, 86, 34, 19, -127, -109, -49, 89, 7, 46, 3, 123, -116, 127, -73, -77, 89, -22, -76, -63, 40, 123, -48, -124, -87, -93, -127, -68, 16, 43, 2, 59, 52, -63, 36, 111, 68, 119, 96, -10, 86, 7, 80, 35, 29, 28, -125, 95, 112, -101, 82, -117, 56, -45, -75, -97, 95, 2, 3, 1, 0, 1, -93, 33, 48, 31, 48, 29, 6, 3, 85, 29, 14, 4, 22, 4, 20, 57, 125, -58, -16, 30, 48, -4, -79, -11, 127, -18, -102, 77, 126, 122, 56, 118, 83, -57, 70, 48, 13, 6, 9, 42, -122, 72, -122, -9, 13, 1, 1, 11, 5, 0, 3, -126, 1, 1, 0, -123, 24, -8, -90, 49, 117, 25, 86, -40, 42, 93, 126, -104, 89, -117, -76, -118, 92, -56, 111, 105, 65, -106, 102, -9, 110, -46, -67, 15, 0, 99, -10, 127, -113, 82, -65, 21, -71, -89, 104, 126, -113, 95, 25, -97, -12, -9, -64, -2, 83, -84, 100, -21, -84, -92, -97, 61, -17, 67, -98, -66, 79, -91, 12, -15, 106, 9, 11, -22, -112, -28, -60, -75, -73, -72, 69, -118, -5, -45, 10, -25, 86, -65, 113, 76, 112, 59, 39, -87, 5, 57, 117, 102, 82, -43, 72, 83, 50, 52, -26, 49, -120, 15, -58, 13, -91, 76, 114, 93, -36, -46, -64, 23, 85, -70, -97, 124, -75, 12, 71, -5, 44, -81, 80, 40, 50, 126, -21, -127, 127, 116, -120, 97, -55, -121, 37, -111, 102, 83, -17, 9, -108, -37, -99, 20, -3, -39, -74, -15, -91, 25, 98, 36, -116, 118, 22, 116, -114, 60, 15, 49, 105, 123, 94, 29, 114, 12, -20, -61, -62, -71, 104, 48, 91, 63, -110, -54, -18, 94, -45, -11, -51, -111, -123, -75, -8, 36, -58, 88, -15, -116, 12, 4, 95, 16, 92, 61, -22, 12, 56, 5, 37, 44, -47, 123, 104, -98, -111, 21, -114, -121, 127, -64, -58, -9, -93, 63, -116, 83, -31, 61, -99, 34, 6, 19, -94, 69, 47, -106, -61, -115, -47, -50, -97, -28, -39, -54, 41, -48, -125, 120, 93, 84, 109, -84, 9, -83, 110, 119, 68, 72, -76, -53, 63, -52, 75]";
String mAppKey = Arrays.toString(Objects.requireNonNull(getSignature(context.getPackageName(), context)));
return mSmartPackKey.equals(mAppKey);
}
private static boolean isUpdateAvailable() {
return BuildConfig.VERSION_CODE < getVersionCode();
}
@SuppressLint("PackageManagerGetSignatures")
private static byte[] getSignature(String packageid, Context context) {
try {
PackageInfo pkgInfo = context.getPackageManager().getPackageInfo(packageid, PackageManager.GET_SIGNATURES);
return signatureToBytes(pkgInfo.signatures);
} catch (PackageManager.NameNotFoundException ignored) {}
return null;
}
private static byte[] signatureToBytes(Signature[] signatures) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
for (Signature sig : signatures) {
try {
outputStream.write(sig.toByteArray());
} catch (IOException ignored) {}
}
return outputStream.toByteArray();
}
private static int getVersionCode() {
if (mJSONObject == null) return 0;
return mVersionCode;
}
private static MaterialAlertDialogBuilder updateAvailableDialog(Activity activity) {
return new MaterialAlertDialogBuilder(activity)
.setIcon(R.mipmap.ic_launcher)
.setTitle(activity.getString(R.string.update_available, getVersionName()))
.setMessage(activity.getString(R.string.change_logs) + "\n" + getChangeLogs())
.setCancelable(false)
.setNegativeButton(activity.getString(R.string.cancel), (dialog, id) -> {
})
.setPositiveButton(activity.getString(R.string.get_it), (dialog, id) -> {
if (sPermissionUtils.isPermissionDenied(Manifest.permission.WRITE_EXTERNAL_STORAGE, activity)) {
sPermissionUtils.requestPermission(new String[] {
Manifest.permission.WRITE_EXTERNAL_STORAGE
}, activity);
sCommonUtils.snackBar(activity.findViewById(android.R.id.content), activity.getString(R.string.storage_access_denied)).show();
return;
}
updaterTask(activity);
});
}
private static String getChangeLogs() {
if (mJSONObject == null) return "";
return mChangeLog;
}
private static String getChecksum() {
if (mJSONObject == null) return "";
return mSHA1;
}
private static String readAll(Reader rd) throws IOException {
StringBuilder sb = new StringBuilder();
int cp;
while ((cp = rd.read()) != -1) {
sb.append((char) cp);
}
return sb.toString();
}
private static String getVersionName() {
if (mJSONObject == null) return "";
return mVersionName;
}
private static String getUrl() {
if (mJSONObject == null) return "";
return mReleaseURL;
}
private static void getLatestApp(Context context) {
if (sPermissionUtils.isPermissionDenied(Manifest.permission.WRITE_EXTERNAL_STORAGE, context)) {
sPermissionUtils.requestPermission(new String[] {
Manifest.permission.WRITE_EXTERNAL_STORAGE
}, (Activity) context);
return;
}
Utils.download(Common.geLatestAPK(context), getUrl());
}
public static void isManualUpdate(boolean b) {
mManualUpdate = b;
}
private static void parseJSON(int updateCheckInterval, Activity activity) {
new sExecutor() {
private long ucTimeStamp;
private int interval;
@Override
public void onPreExecute() {
ucTimeStamp = PreferenceManager.getDefaultSharedPreferences(activity).getLong("ucTimeStamp", 0);
interval = updateCheckInterval * 60 * 60 * 1000;
}
@Override
public void doInBackground() {
if (System.currentTimeMillis() > ucTimeStamp + interval) {
try (InputStream is = new URL(Common.getLatestVersionUrl()).openStream()) {
BufferedReader rd = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
String jsonText = readAll(rd);
mJSONObject = new JSONObject(jsonText);
mChangeLog = sJSONUtils.getString(mJSONObject,"releaseNotes");
mReleaseURL = sJSONUtils.getString(mJSONObject,"releaseUrl");
mSHA1 = sJSONUtils.getString(mJSONObject,"sha1");
mVersionCode = sJSONUtils.getInt(mJSONObject,"latestVersionCode");
mVersionName = sJSONUtils.getString(mJSONObject,"latestVersion");
} catch (JSONException | IOException ignored) {
}
}
}
@Override
public void onPostExecute() {
if (isManualUpdate()) {
if (mJSONObject == null) {
sCommonUtils.snackBar(activity.findViewById(android.R.id.content), activity.getString(R.string.no_internet)).show();
return;
}
if (isUpdateAvailable()) {
updateAvailableDialog(activity).show();
} else {
new MaterialAlertDialogBuilder(activity)
.setIcon(R.mipmap.ic_launcher)
.setTitle(R.string.app_name)
.setMessage(R.string.updated_dialog)
.setPositiveButton(activity.getString(R.string.cancel), (dialog, id) -> {
}).show();
}
} else {
if (mJSONObject == null) {
return;
}
if (isUpdateAvailable()) {
updateAvailableDialog(activity).show();
}
}
PreferenceManager.getDefaultSharedPreferences(activity).edit().putLong("ucTimeStamp", System
.currentTimeMillis()).apply();
}
}.execute();
}
private static void updaterTask(Context context) {
new sExecutor() {
private String mSid = null;
private ProgressDialog mProgressDialog;
@Override
public void onPreExecute() {
mProgressDialog = new ProgressDialog(context);
mProgressDialog.setMessage(context.getString(R.string.downloading, getVersionName() + "..."));
mProgressDialog.setCancelable(false);
mProgressDialog.show();
}
@Override
public void doInBackground() {
getLatestApp(context);
mProgressDialog.setMessage("Installing De-Bloater " + getVersionName() + "...");
Utils.runCommand("sleep 5");
if (Utils.exist(Common.geLatestAPK(context)) && Utils.getChecksum(Common.geLatestAPK(context))
.contains(Objects.requireNonNull(getChecksum()))) {
mSid = Utils.runAndGetOutput("pm install-create").replace(
"Success: created install session [","").replace("]", "");
File mAPK = new File(Common.geLatestAPK(context));
Utils.runCommand("pm install-write -S " + mAPK.length() + " " + mSid + " " + mAPK.getName() + " " + mAPK);
}
}
@Override
public void onPostExecute() {
try {
mProgressDialog.dismiss();
} catch (IllegalArgumentException ignored) {}
if (Utils.exist(Common.geLatestAPK(context)) && Utils.getChecksum(Common.geLatestAPK(context))
.contains(Objects.requireNonNull(getChecksum()))) {
Utils.runCommand("pm install-commit " + mSid);
} else {
new MaterialAlertDialogBuilder(context)
.setMessage(context.getString(R.string.download_failed))
.setNegativeButton(context.getString(R.string.cancel), (dialog, id) -> {
}).show();
}
}
}.execute();
}
public void initialize(int updateCheckInterval, Activity activity) {
parseJSON(updateCheckInterval, activity);
}
}

View file

@ -0,0 +1,169 @@
package com.sunilpaulmathew.debloater.utils;
import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.os.Build;
import android.text.Html;
import android.util.TypedValue;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.sunilpaulmathew.debloater.BuildConfig;
import com.sunilpaulmathew.debloater.R;
import com.topjohnwu.superuser.Shell;
import com.topjohnwu.superuser.ShellUtils;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.List;
import in.sunilpaulmathew.sCommon.CommonUtils.sCommonUtils;
import in.sunilpaulmathew.sCommon.PackageUtils.sPackageUtils;
/*
* Created by sunilpaulmathew <sunil.kde@gmail.com> on October 27, 2020
*/
public class Utils {
static {
Shell.enableVerboseLogging = BuildConfig.DEBUG;
}
public static String getAppStoreURL(Context context) {
if (sPackageUtils.isPackageInstalled("com.android.vending", context)) {
return " Google Play: https://play.google.com/store/apps/details?id=com.sunilpaulmathew.debloater";
} else if (sPackageUtils.isPackageInstalled("org.fdroid.fdroid", context)) {
return " F-Droid: https://f-droid.org/packages/com.sunilpaulmathew.debloater/";
} else {
return " GitHub: https://github.com/sunilpaulmathew/De-Bloater/releases/latest";
}
}
public static int getSpanCount(Activity activity) {
return sCommonUtils.isTablet(activity) ? sCommonUtils.getOrientation(activity) == Configuration.ORIENTATION_LANDSCAPE ?
4 : 3 : sCommonUtils.getOrientation(activity) == Configuration.ORIENTATION_LANDSCAPE ? 3 : 2;
}
public static boolean rootAccess() {
return Shell.getShell().isRoot();
}
public static void runCommand(String command) {
Shell.cmd(command).exec();
}
@NonNull
static String runAndGetOutput(String command) {
StringBuilder sb = new StringBuilder();
try {
List<String> outputs = Shell.cmd(command).exec().getOut();
if (ShellUtils.isValidOutput(outputs)) {
for (String output : outputs) {
sb.append(output).append("\n");
}
}
return removeSuffix(sb.toString()).trim();
} catch (Exception e) {
return "";
}
}
public static boolean magiskSupported() {
return Utils.exist("/sbin/.magisk") || Utils.exist("/data/adb/magisk") || isAPatchSupported() || isKSUSupported();
}
public static int getThemeAccentColor(Context context) {
TypedValue value = new TypedValue();
context.getTheme().resolveAttribute(R.attr.colorAccent, value, true);
return value.data;
}
public static int getPrimaryTextColor(Context context) {
TypedValue value = new TypedValue();
context.getTheme().resolveAttribute(R.attr.colorPrimary, value, true);
return value.data;
}
private static String removeSuffix(@Nullable String s) {
if (s != null && s.endsWith("\n")) {
return s.substring(0, s.length() - "\n".length());
}
return s;
}
public static boolean exist(String file) {
String output = runAndGetOutput("[ -e " + file + " ] && echo true");
return output.equals("true");
}
public static boolean isAPatchSupported() {
return Utils.exist("/data/adb/ap/bin/busybox");
}
public static boolean isKSUSupported() {
return Utils.exist("/data/adb/ksu/bin/busybox");
}
public static void delete(String path) {
runCommand(magiskBusyBox() + "rm -r " + path);
}
public static void create(String text, String path) {
Utils.runCommand(magiskBusyBox() + "echo '" + text + "' > " + path);
}
public static String read(String path) {
return Utils.runAndGetOutput("cat " + path);
}
public static void navigateToFragment(Activity activity) {
BottomNavigationView bottomNavigationView = activity.findViewById(R.id.bottom_navigation);
bottomNavigationView.setSelectedItemId(R.id.nav_active);
}
static void download(String path, String url) {
try (InputStream input = new URL(url).openStream();
FileOutputStream output = new FileOutputStream(path)) {
byte[] data = new byte[4096];
int count;
while ((count = input.read(data)) != -1) {
output.write(data, 0, count);
}
} catch (Exception ignored) {
}
}
static void chmod(String permission, String path) {
runCommand(magiskBusyBox() + "chmod " + permission + " " + path);
}
public static String getChecksum(String path) {
return runAndGetOutput("sha1sum " + path);
}
public static String magiskBusyBox() {
if (Utils.exist("/data/adb/magisk/busybox")) {
return "/data/adb/magisk/busybox ";
} else if (isAPatchSupported()) {
return "/data/adb/ap/bin/busybox ";
} else if (isKSUSupported()) {
return "/data/adb/ksu/bin/busybox ";
} else {
return "";
}
}
public static CharSequence fromHtml(String text) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return Html.fromHtml(text, Html.FROM_HTML_MODE_LEGACY);
} else {
return Html.fromHtml(text);
}
}
}