321 lines
13 KiB
Java
321 lines
13 KiB
Java
|
|
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);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|