diff --git a/.idea/assetWizardSettings.xml b/.idea/assetWizardSettings.xml index 46c3593c..196e99a6 100644 --- a/.idea/assetWizardSettings.xml +++ b/.idea/assetWizardSettings.xml @@ -333,7 +333,9 @@ diff --git a/app/build.gradle b/app/build.gradle index 020e4aaa..fc1501d2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -11,8 +11,8 @@ android { // we're not going to google play //noinspection OldTargetApi targetSdkVersion 27 - versionCode 2050 - versionName "0.2.0-rc5" + versionCode 2060 + versionName "0.2.0-rc6" } signingConfigs { release { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 60ddb01d..2af3d5a7 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -15,8 +15,11 @@ android:supportsRtl="false" android:theme="@style/AppTheme" tools:replace="android:allowBackup"> - + + diff --git a/app/src/main/assets/Scripts b/app/src/main/assets/Scripts index ad15f97c..bc8058ea 160000 --- a/app/src/main/assets/Scripts +++ b/app/src/main/assets/Scripts @@ -1 +1 @@ -Subproject commit ad15f97c8b48f8e746b6e404742fa08881ef3029 +Subproject commit bc8058eaf19dd249755ba56657b20a46d87a99d6 diff --git a/app/src/main/java/org/androidbootmanager/app/roms/ROMsList.java b/app/src/main/java/org/androidbootmanager/app/roms/ROMsList.java index 88c84ac4..18855f56 100644 --- a/app/src/main/java/org/androidbootmanager/app/roms/ROMsList.java +++ b/app/src/main/java/org/androidbootmanager/app/roms/ROMsList.java @@ -29,66 +29,43 @@ public List getROMs() { ROM r = new ROM(); r.scriptname = sn; r.fullPath = "/data/data/org.androidbootmanager.app/assets/Scripts/add_os/" + codename + "/" + r.scriptname; - ArrayList a; - int b; + r.requiredFiles = new HashMap<>(); + r.parts = new ArrayList<>(); + r.strings = new HashMap<>(); + ArrayList a = new ArrayList<>(Arrays.asList(Objects.requireNonNull(SuFile.open("/data/abm/bootset/db/entries/").list()))); + a.removeIf((c) -> !c.contains("rom")); + a.sort((c, d) -> Integer.compare(Integer.parseInt(c.replace("rom","").replace(".conf","")), Integer.parseInt(d.replace("rom","").replace(".conf","")))); + int b = a.size() > 0 ? Integer.parseInt(a.get(a.size()-1).replace("rom","").replace(".conf",""))+1 : 0; switch (r.scriptname) { case "add_ubuntutouch_systemimage_haliumboot.sh": r.viewname = c.getString(R.string.rom_type_add_ut_sysimg_halium); - r.requiredFiles = new HashMap<>(); r.requiredFiles.put("halium-boot.img", c.getString(R.string.select_halium_boot)); r.requiredFiles.put("system.img", c.getString(R.string.select_system_image)); - r.parts = new ArrayList<>(); r.parts.add(c.getString(R.string.select_part, c.getString(R.string.system_part))); r.parts.add(c.getString(R.string.select_part, c.getString(R.string.data_part))); - r.strings = new HashMap<>(); r.strings.put(c.getString(R.string.enter_rom_name), "Ubuntu Touch"); - a = new ArrayList<>(Arrays.asList(Objects.requireNonNull(SuFile.open("/data/abm/bootset/db/entries/").list()))); - a.removeIf((c) -> !c.contains("rom")); - a.sort((c, d) -> Integer.compare(Integer.parseInt(c.replace("rom","").replace(".conf","")), Integer.parseInt(d.replace("rom","").replace(".conf","")))); - b = a.size() > 0 ? Integer.parseInt(a.get(a.size()-1).replace("rom","").replace(".conf",""))+1 : 0; r.strings.put(c.getString(R.string.enter_rom_folder), "rom" + b); r.gen = (imodel, menuName, folderName) -> imodel.setCmdline(Objects.requireNonNull(imodel.getROM().getValue()).fullPath + " '" + folderName + "' '" + menuName + "' " + Objects.requireNonNull(imodel.getParts().getValue()).get(0) + " " + imodel.getParts().getValue().get(1) + " /data/data/org.androidbootmanager.app/cache/system.img /data/data/org.androidbootmanager.app/cache/halium-boot.img"); break; case "add_sailfish.sh": r.viewname = c.getString(R.string.rom_type_add_sailfish); - r.requiredFiles = new HashMap<>(); r.requiredFiles.put("hybris-boot.img", c.getString(R.string.select_hybris_boot)); r.requiredFiles.put("sailfish.img001", c.getString(R.string.select_system_image)); - r.parts = new ArrayList<>(); r.parts.add(c.getString(R.string.select_part, c.getString(R.string.data_part))); - r.strings = new HashMap<>(); r.strings.put(c.getString(R.string.enter_rom_name), "SailfishOS"); - a = new ArrayList<>(Arrays.asList(Objects.requireNonNull(SuFile.open("/data/abm/bootset/db/entries/").list()))); - a.removeIf((c) -> !c.contains("rom")); - a.sort((c, d) -> Integer.compare(Integer.parseInt(c.replace("rom","").replace(".conf","")), Integer.parseInt(d.replace("rom","").replace(".conf","")))); - b = a.size() > 0 ? Integer.parseInt(a.get(a.size()-1).replace("rom","").replace(".conf",""))+1 : 0; r.strings.put(c.getString(R.string.enter_rom_folder), "rom" + b); r.gen = (imodel, menuName, folderName) -> imodel.setCmdline(Objects.requireNonNull(imodel.getROM().getValue()).fullPath + " '" + folderName + "' '" + menuName + "' " + Objects.requireNonNull(imodel.getParts().getValue()).get(0) + " /data/data/org.androidbootmanager.app/cache/sailfish.img001 /data/data/org.androidbootmanager.app/cache/hybris-boot.img"); break; case "other_os.sh": r.viewname = c.getString(R.string.other_os); - r.requiredFiles = new HashMap<>(); r.requiredFiles.put("boot.img", c.getString(R.string.select_boot)); - r.parts = new ArrayList<>(); - r.strings = new HashMap<>(); r.strings.put(c.getString(R.string.enter_rom_name), ""); - a = new ArrayList<>(Arrays.asList(Objects.requireNonNull(SuFile.open("/data/abm/bootset/db/entries/").list()))); - a.removeIf((c) -> !c.contains("rom")); - a.sort((c, d) -> Integer.compare(Integer.parseInt(c.replace("rom","").replace(".conf","")), Integer.parseInt(d.replace("rom","").replace(".conf","")))); - b = a.size() > 0 ? Integer.parseInt(a.get(a.size()-1).replace("rom","").replace(".conf",""))+1 : 0; r.strings.put(c.getString(R.string.enter_rom_folder), "rom" + b); r.gen = (imodel, menuName, folderName) -> imodel.setCmdline(Objects.requireNonNull(imodel.getROM().getValue()).fullPath + " '" + folderName + "' '" + menuName + "' /data/data/org.androidbootmanager.app/cache/boot.img"); break; case "entry_only.sh": r.viewname = c.getString(R.string.empty_entry); - r.requiredFiles = new HashMap<>(); - r.parts = new ArrayList<>(); - r.strings = new HashMap<>(); r.strings.put(c.getString(R.string.enter_rom_name), ""); - a = new ArrayList<>(Arrays.asList(Objects.requireNonNull(SuFile.open("/data/abm/bootset/db/entries/").list()))); - a.removeIf((c) -> !c.contains("rom")); - a.sort((c, d) -> Integer.compare(Integer.parseInt(c.replace("rom","").replace(".conf","")), Integer.parseInt(d.replace("rom","").replace(".conf","")))); - b = a.size() > 0 ? Integer.parseInt(a.get(a.size()-1).replace("rom","").replace(".conf",""))+1 : 0; r.strings.put(c.getString(R.string.enter_rom_folder), "rom" + b); r.gen = (imodel, menuName, folderName) -> imodel.setCmdline(Objects.requireNonNull(imodel.getROM().getValue()).fullPath + " '" + folderName + "' '" + menuName + "'"); break; diff --git a/app/src/main/java/org/androidbootmanager/app/ui/debug/DebugActivity.java b/app/src/main/java/org/androidbootmanager/app/ui/debug/DebugActivity.java new file mode 100644 index 00000000..ebfdf77e --- /dev/null +++ b/app/src/main/java/org/androidbootmanager/app/ui/debug/DebugActivity.java @@ -0,0 +1,36 @@ +package org.androidbootmanager.app.ui.debug; + +import android.app.AlertDialog; +import android.os.Bundle; +import android.view.View; + +import androidx.appcompat.app.AppCompatActivity; + +import com.topjohnwu.superuser.Shell; + +import org.androidbootmanager.app.R; + +import java.util.ArrayList; + +public class DebugActivity extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_debug); + } + + public void errorTest(View v) { + shelldialog("echo out && echo err 1>&2"); + } + + public void shelldialog(String j) { + ArrayList o = new ArrayList<>(); + ArrayList e = new ArrayList<>(); + Shell.Result r = Shell.su(j).to(o, e).exec(); + new AlertDialog.Builder(this) + .setTitle(j) + .setMessage("OUT channel:\n" + String.join("\n", o) + "\nOUT channel using get:\n" + String.join("\n", r.getOut()) + "\nERR channel:\n" + String.join("\n", e) + "\nERR channel using get:\n" + String.join("\n", r.getErr())) + .show(); + } +} \ No newline at end of file diff --git a/app/src/main/java/org/androidbootmanager/app/ui/generalcfg/GeneralCfgFragment.java b/app/src/main/java/org/androidbootmanager/app/ui/generalcfg/GeneralCfgFragment.java index 6488fe6b..77abe0d0 100644 --- a/app/src/main/java/org/androidbootmanager/app/ui/generalcfg/GeneralCfgFragment.java +++ b/app/src/main/java/org/androidbootmanager/app/ui/generalcfg/GeneralCfgFragment.java @@ -5,6 +5,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.Button; import android.widget.EditText; import android.widget.Toast; @@ -17,6 +18,7 @@ import org.androidbootmanager.app.R; import org.androidbootmanager.app.devices.DeviceList; import org.androidbootmanager.app.ui.activities.MainActivity; +import org.androidbootmanager.app.ui.debug.DebugActivity; import org.androidbootmanager.app.ui.home.InstalledViewModel; import org.androidbootmanager.app.ui.updatelk.BlUpdateWizardPageFragment; import org.androidbootmanager.app.ui.wizard.WizardActivity; @@ -41,6 +43,9 @@ public View onCreateView(@NonNull LayoutInflater inflater, a.finish(); }); root.findViewById(R.id.generalcfg_update_bl).setOnClickListener((view) -> startActivity(new Intent(requireActivity(), WizardActivity.class).putExtra("codename",model.getCodename().getValue()).putExtra("StartFragment", BlUpdateWizardPageFragment.class))); + Button debug = root.findViewById(R.id.debug); + if (debug != null) + debug.setOnClickListener((view) -> startActivity(new Intent(requireActivity(), DebugActivity.class))); final String fileName = SuFile.open("/data/abm/bootset/lk2nd/lk2nd.conf").exists() ? "/data/abm/bootset/lk2nd/lk2nd.conf" : "/data/abm/bootset/lk2nd/db.conf"; try { diff --git a/app/src/main/java/org/androidbootmanager/app/ui/roms/ROMFragment.java b/app/src/main/java/org/androidbootmanager/app/ui/roms/ROMFragment.java index 73c34983..8effe127 100644 --- a/app/src/main/java/org/androidbootmanager/app/ui/roms/ROMFragment.java +++ b/app/src/main/java/org/androidbootmanager/app/ui/roms/ROMFragment.java @@ -81,6 +81,10 @@ public void onBindViewHolder(@NonNull ROMRecyclerViewAdapter.ViewHolder holder, holder.label.setText(getString(R.string.ut)); holder.pic.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ut_logo)); break; + case "SFOS": + holder.label.setText(getString(R.string.rom_type_add_sailfish)); + holder.pic.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_sailfish_os_logo)); + break; case "droid": holder.label.setText(getString(R.string.android)); holder.pic.setImageDrawable(ContextCompat.getDrawable(requireContext(),R.drawable.ic_roms)); diff --git a/app/src/main/java/org/androidbootmanager/app/ui/sdcard/SDCardFragment.java b/app/src/main/java/org/androidbootmanager/app/ui/sdcard/SDCardFragment.java index d0c5afa3..c8778b46 100644 --- a/app/src/main/java/org/androidbootmanager/app/ui/sdcard/SDCardFragment.java +++ b/app/src/main/java/org/androidbootmanager/app/ui/sdcard/SDCardFragment.java @@ -33,6 +33,7 @@ import org.androidbootmanager.app.util.SOUtils; import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Objects; @@ -150,7 +151,7 @@ public ViewHolder(View view) { @Override public void onItemSelected(AdapterView parent, View view, int position, long id) { if (ddresolv[position].equals(ddresolv[3])) - slider.setValues(0f, 7340031f); + slider.setValues(0f, 7340031f); // TODO: un-hardcode } @Override @@ -200,13 +201,15 @@ public void afterTextChanged(Editable s) { dd.setAdapter(new ArrayAdapter<>(requireActivity(), android.R.layout.simple_spinner_dropdown_item, new String[]{getString(R.string.portable_part), getString(R.string.data_part), getString(R.string.meta_part), getString(R.string.system_part), getString(R.string.unknown_part)})); start.setText(String.valueOf(meta.dumpS(id).startSector)); end.setText(String.valueOf(meta.dumpS(id).endSector)); + ArrayList out = new ArrayList<>(); + ArrayList err = new ArrayList<>(); new AlertDialog.Builder(requireContext()) .setTitle(getString(R.string.free_space_size, meta.dumpS(id).sizeFancy)) .setView(v) .setNegativeButton(R.string.cancel, (d, p) -> d.dismiss()) - .setPositiveButton(R.string.create, (d, p) -> MiscUtils.w(requireContext(), R.string.creating_prog, () -> Shell.su(SDUtils.umsd(meta) + " && sgdisk " + bdev + " --new " + meta.nid + ":" + start.getText() + ":" + end.getText() + " --typecode " + meta.nid + ":" + ddresolv[dd.getSelectedItemPosition()] + " --change-name " + meta.nid + ":'" + label.getText().toString().replace("'", "") + "' && ls " + pbdev + meta.nid + (ddresolv[dd.getSelectedItemPosition()].equals("0700") ? (" && sm format public:" + meta.major + "," + (meta.minor + meta.nid)) : (ddresolv[dd.getSelectedItemPosition()].equals("8301") ? " && mkfs.ext4 " + pbdev + meta.nid : " && true"))).submit(MiscUtils.w2((r) -> new AlertDialog.Builder(requireContext()) + .setPositiveButton(R.string.create, (d, p) -> MiscUtils.w(requireContext(), R.string.creating_prog, () -> Shell.su(SDUtils.umsd(meta) + " && sgdisk " + bdev + " --new " + meta.nid + ":" + start.getText() + ":" + end.getText() + " --typecode " + meta.nid + ":" + ddresolv[dd.getSelectedItemPosition()] + " --change-name " + meta.nid + ":'" + label.getText().toString().replace("'", "") + "' && sleep 1 && ls " + pbdev + meta.nid + (ddresolv[dd.getSelectedItemPosition()].equals("0700") ? (" && sm format public:" + meta.major + "," + (meta.minor + meta.nid)) : (ddresolv[dd.getSelectedItemPosition()].equals("8301") ? " && mkfs.ext4 " + pbdev + meta.nid : " && echo Warning: Unsure on how to format this partition."))).to(out, err).submit(MiscUtils.w2((r) -> new AlertDialog.Builder(requireContext()) .setTitle(r.isSuccess() ? R.string.successful : R.string.failed) - .setMessage(String.join("\n", r.getOut()) + "\n" + String.join("\n", r.getErr()) + (String.join("", r.getOut()).contains("old") ? "IMPORTANT: Please reboot!" : "")) + .setMessage(String.join("\n", out) + "\n" + String.join("\n", err) + (String.join("", out).contains("old") ? "IMPORTANT: Please reboot!" : "")) .setPositiveButton(R.string.ok, (g, l) -> recyclerView.setAdapter(new SDRecyclerViewAdapter(generateMeta(DeviceList.getModel(Objects.requireNonNull(model.getCodename().getValue())))))) .setCancelable(false) .show())))) @@ -235,20 +238,22 @@ public void afterTextChanged(Editable s) { dd.setEnabled(false); slider.setEnabled(false); label.setText(meta.dumpS(id).name); + ArrayList out = new ArrayList<>(); + ArrayList err = new ArrayList<>(); new AlertDialog.Builder(requireContext()) .setTitle(getString(R.string.partid, meta.dumpS(id).id, meta.dumpS(id).name)) .setNeutralButton(R.string.cancel, (d, p) -> d.dismiss()) .setNegativeButton(R.string.delete, (w, p1) -> MiscUtils.sure(requireContext(), w, getString(R.string.delete_msg, meta.dumpS(id).id, SDUtils.codes.get(meta.dumpS(id).code), meta.dumpS(id).name), (d, p) -> { - MiscUtils.w(requireContext(), R.string.delete_prog, () -> Shell.su(SDUtils.umsd(meta) + " && sgdisk " + bdev + " --delete " + meta.dumpS(id).id).submit(MiscUtils.w2((r) -> new AlertDialog.Builder(requireContext()) + MiscUtils.w(requireContext(), R.string.delete_prog, () -> Shell.su(SDUtils.umsd(meta) + " && sgdisk " + bdev + " --delete " + meta.dumpS(id).id).to(out, err).submit(MiscUtils.w2((r) -> new AlertDialog.Builder(requireContext()) .setTitle(r.isSuccess() ? R.string.successful : R.string.failed) - .setMessage(String.join("\n", r.getOut()) + "\n" + String.join("", r.getErr()) + (String.join("", r.getOut()).contains("old") ? "IMPORTANT: Please reboot!" : "")) + .setMessage(String.join("\n", out) + "\n" + String.join("", err) + (String.join("", out).contains("old") ? "IMPORTANT: Please reboot!" : "")) .setPositiveButton(R.string.ok, (g, s) -> recyclerView.setAdapter(new SDRecyclerViewAdapter(generateMeta(DeviceList.getModel(Objects.requireNonNull(model.getCodename().getValue())))))) .setCancelable(false) .show()))); })) - .setPositiveButton(R.string.rename, (d, p) -> MiscUtils.w(requireContext(), R.string.renaming_prog, () -> Shell.su(SDUtils.umsd(meta) + " && sgdisk " + bdev + " --change-name " + meta.dumpS(id).id + ":'" + label.getText().toString().replace("'","") + "'").submit(MiscUtils.w2((r) -> new AlertDialog.Builder(requireContext()) + .setPositiveButton(R.string.rename, (d, p) -> MiscUtils.w(requireContext(), R.string.renaming_prog, () -> Shell.su(SDUtils.umsd(meta) + " && sgdisk " + bdev + " --change-name " + meta.dumpS(id).id + ":'" + label.getText().toString().replace("'","") + "'").to(out, err).submit(MiscUtils.w2((r) -> new AlertDialog.Builder(requireContext()) .setTitle(r.isSuccess() ? R.string.successful : R.string.failed) - .setMessage(String.join("\n", r.getOut()) + "\n" + String.join("", r.getErr()) + (String.join("", r.getOut()).contains("old") ? "IMPORTANT: Please reboot!" : "")) + .setMessage(String.join("\n", out) + "\n" + String.join("", err) + (String.join("", out).contains("old") ? "IMPORTANT: Please reboot!" : "")) .setPositiveButton(R.string.ok, (g, s) -> recyclerView.setAdapter(new SDRecyclerViewAdapter(generateMeta(DeviceList.getModel(Objects.requireNonNull(model.getCodename().getValue())))))) .setCancelable(false) .show())))) @@ -272,27 +277,29 @@ public View onCreateView(@NonNull LayoutInflater inflater, SDUtils.setupCodes(requireContext()); AtomicReference meta = new AtomicReference<>(generateMeta(DeviceList.getModel(Objects.requireNonNull(model.getCodename().getValue())))); if (meta.get() == null) { - if (String.join("",Shell.su("sgdisk " + bdev + " --print").exec().getOut()).contains("invalid GPT and valid MBR")) + if (String.join("",Shell.su("sgdisk " + bdev + " --print").exec().getOut()).contains("invalid GPT and valid MBR")) { + ArrayList out = new ArrayList<>(); + ArrayList err = new ArrayList<>(); new AlertDialog.Builder(requireActivity()) - .setNegativeButton("Close", (d, p) -> requireActivity().finish()) - .setCancelable(false) - .setMessage(R.string.sd_mbr) - .setTitle(R.string.fatal) - .setPositiveButton(R.string.convert, (d, p) -> MiscUtils.w(requireContext(), R.string.convert_prog, () -> Shell.su("sm unmount `sm list-volumes public` && sgdisk " + bdev + " --mbrtogpt").submit(MiscUtils.w2((r) -> new AlertDialog.Builder(requireActivity()) - .setTitle(r.isSuccess() ? R.string.successful : R.string.failed) - .setMessage(String.join("\n", r.getOut()) + "\n" + String.join("\n", r.getErr())) - .setCancelable(false) - .setPositiveButton(R.string.ok, (d2, p2) -> { - if (r.isSuccess()) { - meta.set(generateMeta(DeviceList.getModel(Objects.requireNonNull(model.getCodename().getValue())))); - recyclerView.setAdapter(new SDRecyclerViewAdapter(meta.get())); - } else { - requireActivity().finish(); - } - }) - .show())))) - .show(); - else + .setNegativeButton("Close", (d, p) -> requireActivity().finish()) + .setCancelable(false) + .setMessage(R.string.sd_mbr) + .setTitle(R.string.fatal) + .setPositiveButton(R.string.convert, (d, p) -> MiscUtils.w(requireContext(), R.string.convert_prog, () -> Shell.su("sm unmount `sm list-volumes public` && sgdisk " + bdev + " --mbrtogpt").to(out, err).submit(MiscUtils.w2((r) -> new AlertDialog.Builder(requireActivity()) + .setTitle(r.isSuccess() ? R.string.successful : R.string.failed) + .setMessage(String.join("\n", out) + "\n" + String.join("\n", err)) + .setCancelable(false) + .setPositiveButton(R.string.ok, (d2, p2) -> { + if (r.isSuccess()) { + meta.set(generateMeta(DeviceList.getModel(Objects.requireNonNull(model.getCodename().getValue())))); + recyclerView.setAdapter(new SDRecyclerViewAdapter(meta.get())); + } else { + requireActivity().finish(); + } + }) + .show())))) + .show(); + } else new AlertDialog.Builder(requireActivity()) .setNegativeButton("Close", (d, p) -> requireActivity().finish()) .setCancelable(false) diff --git a/app/src/main/res/drawable/ic_sailfish_os_logo.xml b/app/src/main/res/drawable/ic_sailfish_os_logo.xml new file mode 100644 index 00000000..35a969ef --- /dev/null +++ b/app/src/main/res/drawable/ic_sailfish_os_logo.xml @@ -0,0 +1,11 @@ + + + + + + diff --git a/app/src/main/res/drawable/ut_logo.xml b/app/src/main/res/drawable/ut_logo.xml index 79dd7912..cab791e4 100644 --- a/app/src/main/res/drawable/ut_logo.xml +++ b/app/src/main/res/drawable/ut_logo.xml @@ -5,10 +5,10 @@ android:viewportWidth="425.197" android:viewportHeight="425.197"> diff --git a/app/src/main/res/layout/activity_debug.xml b/app/src/main/res/layout/activity_debug.xml new file mode 100644 index 00000000..5adb3374 --- /dev/null +++ b/app/src/main/res/layout/activity_debug.xml @@ -0,0 +1,20 @@ + + + +