mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-28 04:25:27 +00:00
Add boot image file patch
This commit is contained in:
parent
dbe6e5b3d7
commit
db8fd2c913
@ -1,5 +1,6 @@
|
||||
package com.topjohnwu.magisk;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.ActionBar;
|
||||
@ -8,12 +9,17 @@ import android.support.v7.widget.Toolbar;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.topjohnwu.magisk.asyncs.FlashZip;
|
||||
import com.topjohnwu.magisk.asyncs.PatchBootImage;
|
||||
import com.topjohnwu.magisk.components.Activity;
|
||||
import com.topjohnwu.magisk.utils.AdaptiveList;
|
||||
import com.topjohnwu.magisk.utils.Shell;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
@ -21,11 +27,15 @@ import butterknife.OnClick;
|
||||
|
||||
public class FlashActivity extends Activity {
|
||||
|
||||
public static final String SET_ACTION = "action";
|
||||
public static final String SET_BOOT_URI = "boot_uri";
|
||||
public static final String FLASH_ZIP = "flash";
|
||||
public static final String PATCH_BOOT = "patch";
|
||||
|
||||
@BindView(R.id.toolbar) Toolbar toolbar;
|
||||
@BindView(R.id.flash_logs) RecyclerView flashLogs;
|
||||
@BindView(R.id.button_panel) LinearLayout buttonPanel;
|
||||
|
||||
private AdaptiveList<String> rootShellOutput;
|
||||
@BindView(R.id.reboot) Button reboot;
|
||||
|
||||
@OnClick(R.id.no_thanks)
|
||||
public void dismiss() {
|
||||
@ -42,22 +52,33 @@ public class FlashActivity extends Activity {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_flash);
|
||||
ButterKnife.bind(this);
|
||||
rootShellOutput = new AdaptiveList<>(flashLogs);
|
||||
AdaptiveList<String> rootShellOutput = new AdaptiveList<>(flashLogs);
|
||||
setSupportActionBar(toolbar);
|
||||
ActionBar ab = getSupportActionBar();
|
||||
if (ab != null) {
|
||||
ab.setTitle(R.string.flashing);
|
||||
}
|
||||
setFloating();
|
||||
if (!Shell.rootAccess())
|
||||
reboot.setVisibility(View.GONE);
|
||||
|
||||
flashLogs.setAdapter(new FlashLogAdapter());
|
||||
flashLogs.setAdapter(new FlashLogAdapter(rootShellOutput));
|
||||
|
||||
// We must receive a Uri of the target zip
|
||||
Uri uri = getIntent().getData();
|
||||
Intent intent = getIntent();
|
||||
Uri uri = intent.getData();
|
||||
|
||||
new FlashZip(this, uri, rootShellOutput)
|
||||
.setCallBack(() -> buttonPanel.setVisibility(View.VISIBLE))
|
||||
.exec();
|
||||
switch (getIntent().getStringExtra(SET_ACTION)) {
|
||||
case FLASH_ZIP:
|
||||
new FlashZip(this, uri, rootShellOutput)
|
||||
.setCallBack(() -> buttonPanel.setVisibility(View.VISIBLE))
|
||||
.exec();
|
||||
break;
|
||||
case PATCH_BOOT:
|
||||
new PatchBootImage(this, uri, intent.getParcelableExtra(SET_BOOT_URI), rootShellOutput)
|
||||
.setCallBack(() -> buttonPanel.setVisibility(View.VISIBLE))
|
||||
.exec();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -65,7 +86,13 @@ public class FlashActivity extends Activity {
|
||||
// Prevent user accidentally press back button
|
||||
}
|
||||
|
||||
private class FlashLogAdapter extends RecyclerView.Adapter<ViewHolder> {
|
||||
private static class FlashLogAdapter extends RecyclerView.Adapter<ViewHolder> {
|
||||
|
||||
private List<String> mList;
|
||||
|
||||
FlashLogAdapter(List<String> list) {
|
||||
mList = list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
@ -76,16 +103,16 @@ public class FlashActivity extends Activity {
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(ViewHolder holder, int position) {
|
||||
holder.text.setText(rootShellOutput.get(position));
|
||||
holder.text.setText(mList.get(position));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return rootShellOutput.size();
|
||||
return mList.size();
|
||||
}
|
||||
}
|
||||
|
||||
public class ViewHolder extends RecyclerView.ViewHolder {
|
||||
public static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
@BindView(R.id.textView) TextView text;
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
package com.topjohnwu.magisk;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
@ -49,15 +51,15 @@ import butterknife.Unbinder;
|
||||
public class MagiskFragment extends Fragment
|
||||
implements Topic.Subscriber, SwipeRefreshLayout.OnRefreshListener, ExpandableView {
|
||||
|
||||
public static final String SHOW_DIALOG = "dialog";
|
||||
|
||||
private static final String UNINSTALLER = "magisk_uninstaller.sh";
|
||||
private static final String UTIL_FUNCTIONS= "util_functions.sh";
|
||||
private static final int SELECT_BOOT_IMG = 3;
|
||||
|
||||
private Container expandableContainer = new Container();
|
||||
|
||||
private MagiskManager magiskManager;
|
||||
private Unbinder unbinder;
|
||||
private static boolean shownDialog = false;
|
||||
|
||||
@BindView(R.id.swipeRefreshLayout) SwipeRefreshLayout mSwipeRefreshLayout;
|
||||
|
||||
@ -108,6 +110,7 @@ public class MagiskFragment extends Fragment
|
||||
|
||||
@OnClick(R.id.install_button)
|
||||
public void install() {
|
||||
shownDialog = true;
|
||||
String bootImage = null;
|
||||
if (Shell.rootAccess()) {
|
||||
if (magiskManager.bootBlock != null) {
|
||||
@ -117,54 +120,83 @@ public class MagiskFragment extends Fragment
|
||||
if (idx > 0) {
|
||||
bootImage = magiskManager.blockList.get(idx - 1);
|
||||
} else {
|
||||
SnackbarMaker.make(getActivity(), R.string.manual_boot_image, Snackbar.LENGTH_LONG).show();
|
||||
SnackbarMaker.make(getActivity(),
|
||||
R.string.manual_boot_image, Snackbar.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
final String boot = bootImage;
|
||||
((NotificationManager) getActivity().getSystemService(Context.NOTIFICATION_SERVICE)).cancelAll();
|
||||
final String finalBootImage = bootImage;
|
||||
String filename = "Magisk-v" + magiskManager.remoteMagiskVersionString + ".zip";
|
||||
new AlertDialogBuilder(getActivity())
|
||||
.setTitle(getString(R.string.repo_install_title, getString(R.string.magisk)))
|
||||
.setMessage(getString(R.string.repo_install_msg, filename))
|
||||
.setCancelable(true)
|
||||
.setPositiveButton(Shell.rootAccess() ? R.string.install : R.string.download,
|
||||
(d, i) ->
|
||||
Utils.dlAndReceive(
|
||||
getActivity(),
|
||||
new DownloadReceiver() {
|
||||
private String boot = finalBootImage;
|
||||
private boolean enc = keepEncChkbox.isChecked();
|
||||
private boolean verity = keepVerityChkbox.isChecked();
|
||||
|
||||
@Override
|
||||
public void onDownloadDone(Uri uri) {
|
||||
if (Shell.rootAccess()) {
|
||||
getShell().su_raw(
|
||||
"rm -f /dev/.magisk",
|
||||
"echo \"BOOTIMAGE=" + boot + "\" >> /dev/.magisk",
|
||||
"echo \"KEEPFORCEENCRYPT=" + String.valueOf(enc) + "\" >> /dev/.magisk",
|
||||
"echo \"KEEPVERITY=" + String.valueOf(verity) + "\" >> /dev/.magisk"
|
||||
);
|
||||
startActivity(new Intent(getActivity(), FlashActivity.class).setData(uri));
|
||||
} else {
|
||||
Utils.showUriSnack(getActivity(), uri);
|
||||
}
|
||||
}
|
||||
},
|
||||
magiskManager.magiskLink,
|
||||
Utils.getLegalFilename(filename))
|
||||
)
|
||||
.setNeutralButton(R.string.release_notes, (d, i) -> {
|
||||
if (magiskManager.releaseNoteLink != null) {
|
||||
Intent openReleaseNoteLink = new Intent(Intent.ACTION_VIEW, Uri.parse(magiskManager.releaseNoteLink));
|
||||
openReleaseNoteLink.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
magiskManager.startActivity(openReleaseNoteLink);
|
||||
.setTitle(getString(R.string.repo_install_title, getString(R.string.magisk)))
|
||||
.setMessage(getString(R.string.repo_install_msg, filename))
|
||||
.setCancelable(true)
|
||||
.setPositiveButton(
|
||||
R.string.install,
|
||||
(d, i) -> {
|
||||
List<String> options = new ArrayList<>();
|
||||
options.add(getString(R.string.download_zip_only));
|
||||
options.add(getString(R.string.patch_boot_file));
|
||||
if (Shell.rootAccess()) {
|
||||
options.add(getString(R.string.direct_install));
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.no_thanks, null)
|
||||
.show();
|
||||
new AlertDialog.Builder(getActivity())
|
||||
.setTitle(R.string.select_method)
|
||||
.setItems(
|
||||
options.toArray(new String [0]),
|
||||
(dialog, idx) -> {
|
||||
DownloadReceiver receiver = null;
|
||||
switch (idx) {
|
||||
case 1:
|
||||
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
|
||||
intent.setType("*/*");
|
||||
startActivityForResult(intent, SELECT_BOOT_IMG);
|
||||
return;
|
||||
case 0:
|
||||
receiver = new DownloadReceiver() {
|
||||
@Override
|
||||
public void onDownloadDone(Uri uri) {
|
||||
Utils.showUriSnack(getActivity(), uri);
|
||||
}
|
||||
};
|
||||
break;
|
||||
case 2:
|
||||
receiver = new DownloadReceiver() {
|
||||
@Override
|
||||
public void onDownloadDone(Uri uri) {
|
||||
getShell().su_raw(
|
||||
"echo \"BOOTIMAGE=" + boot + "\" > /dev/.magisk",
|
||||
"echo \"KEEPFORCEENCRYPT=" + keepEncChkbox.isChecked() + "\" >> /dev/.magisk",
|
||||
"echo \"KEEPVERITY=" + keepVerityChkbox.isChecked() + "\" >> /dev/.magisk"
|
||||
);
|
||||
Intent intent = new Intent(getActivity(), FlashActivity.class);
|
||||
intent.setData(uri).putExtra(FlashActivity.SET_ACTION, FlashActivity.FLASH_ZIP);
|
||||
startActivity(intent);
|
||||
}
|
||||
};
|
||||
break;
|
||||
}
|
||||
Utils.dlAndReceive(
|
||||
getActivity(),
|
||||
receiver,
|
||||
magiskManager.magiskLink,
|
||||
Utils.getLegalFilename(filename)
|
||||
);
|
||||
}
|
||||
).show();
|
||||
}
|
||||
)
|
||||
.setNeutralButton(R.string.release_notes, (d, i) -> {
|
||||
if (magiskManager.releaseNoteLink != null) {
|
||||
Intent openReleaseNoteLink = new Intent(Intent.ACTION_VIEW, Uri.parse(magiskManager.releaseNoteLink));
|
||||
openReleaseNoteLink.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
magiskManager.startActivity(openReleaseNoteLink);
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.no_thanks, null)
|
||||
.show();
|
||||
}
|
||||
|
||||
@OnClick(R.id.uninstall_button)
|
||||
@ -172,7 +204,7 @@ public class MagiskFragment extends Fragment
|
||||
new AlertDialogBuilder(getActivity())
|
||||
.setTitle(R.string.uninstall_magisk_title)
|
||||
.setMessage(R.string.uninstall_magisk_msg)
|
||||
.setPositiveButton(R.string.yes, (dialogInterface, i) -> {
|
||||
.setPositiveButton(R.string.yes, (d, i) -> {
|
||||
try {
|
||||
InputStream in = magiskManager.getAssets().open(UNINSTALLER);
|
||||
File uninstaller = new File(magiskManager.getCacheDir(), UNINSTALLER);
|
||||
@ -254,6 +286,8 @@ public class MagiskFragment extends Fragment
|
||||
magiskManager.remoteMagiskVersionCode = -1;
|
||||
collapse();
|
||||
|
||||
shownDialog = false;
|
||||
|
||||
// Trigger state check
|
||||
if (Utils.checkNetworkStatus(magiskManager)) {
|
||||
new CheckUpdates(getActivity()).exec();
|
||||
@ -262,6 +296,28 @@ public class MagiskFragment extends Fragment
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (requestCode == SELECT_BOOT_IMG && resultCode == Activity.RESULT_OK && data != null) {
|
||||
Utils.dlAndReceive(
|
||||
getActivity(),
|
||||
new DownloadReceiver() {
|
||||
@Override
|
||||
public void onDownloadDone(Uri uri) {
|
||||
// Get the URI of the selected file
|
||||
Intent intent = new Intent(getActivity(), FlashActivity.class);
|
||||
intent.setData(uri)
|
||||
.putExtra(FlashActivity.SET_BOOT_URI, data.getData())
|
||||
.putExtra(FlashActivity.SET_ACTION, FlashActivity.PATCH_BOOT);
|
||||
startActivity(intent);
|
||||
}
|
||||
},
|
||||
magiskManager.magiskLink,
|
||||
Utils.getLegalFilename("Magisk-v" + magiskManager.remoteMagiskVersionString + ".zip")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTopicPublished(Topic topic) {
|
||||
if (topic == magiskManager.updateCheckDone) {
|
||||
@ -341,7 +397,7 @@ public class MagiskFragment extends Fragment
|
||||
rootStatusIcon.setColorFilter(color);
|
||||
|
||||
if (!Shell.rootAccess()) {
|
||||
installText.setText(R.string.download);
|
||||
installText.setText(R.string.install);
|
||||
} else {
|
||||
if (magiskManager.remoteMagiskVersionCode > magiskManager.magiskVersionCode) {
|
||||
installText.setText(R.string.update);
|
||||
@ -384,7 +440,7 @@ public class MagiskFragment extends Fragment
|
||||
magiskUpdateProgress.setVisibility(View.GONE);
|
||||
mSwipeRefreshLayout.setRefreshing(false);
|
||||
|
||||
if (magiskManager.remoteMagiskVersionCode > magiskManager.magiskVersionCode)
|
||||
if (magiskManager.remoteMagiskVersionCode > magiskManager.magiskVersionCode && !shownDialog)
|
||||
install();
|
||||
}
|
||||
|
||||
|
@ -87,7 +87,7 @@ public class ModulesFragment extends Fragment implements Topic.Subscriber {
|
||||
if (requestCode == FETCH_ZIP_CODE && resultCode == Activity.RESULT_OK && data != null) {
|
||||
// Get the URI of the selected file
|
||||
Intent intent = new Intent(getActivity(), FlashActivity.class);
|
||||
intent.setData(data.getData()).putExtra("ACTION", "flash");
|
||||
intent.setData(data.getData()).putExtra(FlashActivity.SET_ACTION, FlashActivity.FLASH_ZIP);
|
||||
startActivity(intent);
|
||||
}
|
||||
}
|
||||
|
@ -139,6 +139,7 @@ public class SettingsActivity extends Activity implements Topic.Subscriber {
|
||||
if (!Shell.rootAccess()) {
|
||||
prefScreen.removePreference(magiskCategory);
|
||||
prefScreen.removePreference(suCategory);
|
||||
generalCatagory.removePreference(hideManager);
|
||||
} else {
|
||||
if (!magiskManager.isSuClient) {
|
||||
prefScreen.removePreference(suCategory);
|
||||
|
@ -18,7 +18,7 @@ import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.List;
|
||||
|
||||
public class FlashZip extends ParallelTask<Void, String, Integer> {
|
||||
public class FlashZip extends ParallelTask<Void, Void, Integer> {
|
||||
|
||||
private Uri mUri;
|
||||
private File mCachedFile, mScriptFile, mCheckFile;
|
||||
@ -40,7 +40,7 @@ public class FlashZip extends ParallelTask<Void, String, Integer> {
|
||||
}
|
||||
|
||||
private boolean unzipAndCheck() throws Exception {
|
||||
ZipUtils.unzip(mCachedFile, mCachedFile.getParentFile(), "META-INF/com/google/android");
|
||||
ZipUtils.unzip(mCachedFile, mCachedFile.getParentFile(), "META-INF/com/google/android", false);
|
||||
List<String> ret = Utils.readFile(getShell(), mCheckFile.getPath());
|
||||
return Utils.isValidShellResponse(ret) && ret.get(0).contains("#MAGISK");
|
||||
}
|
||||
@ -52,7 +52,7 @@ public class FlashZip extends ParallelTask<Void, String, Integer> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onProgressUpdate(String... values) {
|
||||
protected void onProgressUpdate(Void... values) {
|
||||
mList.updateView();
|
||||
}
|
||||
|
||||
@ -61,18 +61,18 @@ public class FlashZip extends ParallelTask<Void, String, Integer> {
|
||||
MagiskManager magiskManager = getMagiskManager();
|
||||
if (magiskManager == null) return -1;
|
||||
try {
|
||||
mList.add(magiskManager.getString(R.string.copying_msg));
|
||||
mList.add("- Copying zip to temp directory");
|
||||
|
||||
mCachedFile.delete();
|
||||
try (
|
||||
InputStream in = magiskManager.getContentResolver().openInputStream(mUri);
|
||||
OutputStream outputStream = new FileOutputStream(mCachedFile)
|
||||
OutputStream out = new FileOutputStream(mCachedFile)
|
||||
) {
|
||||
if (in == null) throw new FileNotFoundException();
|
||||
byte buffer[] = new byte[1024];
|
||||
int length;
|
||||
while ((length = in.read(buffer)) > 0)
|
||||
outputStream.write(buffer, 0, length);
|
||||
out.write(buffer, 0, length);
|
||||
} catch (FileNotFoundException e) {
|
||||
mList.add("! Invalid Uri");
|
||||
throw e;
|
||||
@ -81,7 +81,7 @@ public class FlashZip extends ParallelTask<Void, String, Integer> {
|
||||
throw e;
|
||||
}
|
||||
if (!unzipAndCheck()) return 0;
|
||||
mList.add(magiskManager.getString(R.string.zip_install_progress_msg, mFilename));
|
||||
mList.add("- Installing " + mFilename);
|
||||
getShell().su(mList,
|
||||
"BOOTMODE=true sh " + mScriptFile + " dummy 1 " + mCachedFile +
|
||||
" && echo 'Success!' || echo 'Failed!'"
|
||||
|
@ -0,0 +1,145 @@
|
||||
package com.topjohnwu.magisk.asyncs;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.topjohnwu.magisk.MagiskManager;
|
||||
import com.topjohnwu.magisk.utils.AdaptiveList;
|
||||
import com.topjohnwu.magisk.utils.ZipUtils;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class PatchBootImage extends ParallelTask<Void, Void, Boolean> {
|
||||
|
||||
private Uri mBootImg, mZip;
|
||||
private AdaptiveList<String> mList;
|
||||
private File dest;
|
||||
|
||||
public PatchBootImage(Activity context, Uri zip, Uri boot, AdaptiveList<String> list) {
|
||||
super(context);
|
||||
mBootImg = boot;
|
||||
mList = list;
|
||||
mZip = zip;
|
||||
dest = new File(Environment.getExternalStorageDirectory() + "/MagiskManager/" + "patched_boot.img");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
// UI updates must run in the UI thread
|
||||
mList.setCallback(this::publishProgress);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onProgressUpdate(Void... values) {
|
||||
mList.updateView();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Boolean doInBackground(Void... voids) {
|
||||
MagiskManager magiskManager = getMagiskManager();
|
||||
if (magiskManager == null) return false;
|
||||
|
||||
File install = new File(magiskManager.getApplicationInfo().dataDir, "install");
|
||||
getShell().sh_raw("rm -rf " + install);
|
||||
|
||||
List<String> abis = Arrays.asList(Build.SUPPORTED_ABIS);
|
||||
String arch;
|
||||
if (abis.contains("x86_64")) arch = "x64";
|
||||
else if (abis.contains("arm64-v8a")) arch = "arm64";
|
||||
else if (abis.contains("x86")) arch = "x86";
|
||||
else arch = "arm";
|
||||
mList.add("- Device platform: " + arch);
|
||||
|
||||
try {
|
||||
// Unzip files
|
||||
mList.add("- Extracting files");
|
||||
try (InputStream in = magiskManager.getContentResolver().openInputStream(mZip)) {
|
||||
if (in == null) throw new FileNotFoundException();
|
||||
BufferedInputStream buf = new BufferedInputStream(in);
|
||||
buf.mark(Integer.MAX_VALUE);
|
||||
ZipUtils.unzip(buf, install, arch, true);
|
||||
buf.reset();
|
||||
ZipUtils.unzip(buf, install, "common", true);
|
||||
buf.reset();
|
||||
ZipUtils.unzip(buf, install, "chromeos", false);
|
||||
buf.reset();
|
||||
ZipUtils.unzip(buf, install, "META-INF/com/google/android/update-binary", true);
|
||||
} catch (FileNotFoundException e) {
|
||||
mList.add("! Invalid Uri");
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
mList.add("! Cannot unzip zip");
|
||||
throw e;
|
||||
}
|
||||
|
||||
// Copy boot image
|
||||
File boot = new File(install, "boot.img");
|
||||
try (
|
||||
InputStream in = magiskManager.getContentResolver().openInputStream(mBootImg);
|
||||
OutputStream out = new FileOutputStream(boot);
|
||||
) {
|
||||
if (in == null) throw new FileNotFoundException();
|
||||
byte buffer[] = new byte[1024];
|
||||
int length;
|
||||
while ((length = in.read(buffer)) > 0)
|
||||
out.write(buffer, 0, length);
|
||||
} catch (FileNotFoundException e) {
|
||||
mList.add("! Invalid Uri");
|
||||
throw e;
|
||||
} catch (IOException e) {
|
||||
mList.add("! Copy failed");
|
||||
throw e;
|
||||
}
|
||||
|
||||
mList.add("- Use boot image: " + boot);
|
||||
|
||||
// Patch boot image
|
||||
getShell().sh(mList,
|
||||
"chmod -R 755 " + install,
|
||||
"cd " + install,
|
||||
"sh update-binary indep boot_patch.sh " + boot +
|
||||
" && echo 'Success!' || echo 'Failed!'"
|
||||
);
|
||||
|
||||
if (!TextUtils.equals(mList.get(mList.size() - 1), "Success!"))
|
||||
return false;
|
||||
|
||||
// Move boot image
|
||||
File source = new File(install, "new-boot.img");
|
||||
dest.getParentFile().mkdirs();
|
||||
getShell().sh_raw("mv " + source + " " + dest);
|
||||
|
||||
// Finals
|
||||
getShell().sh_raw(
|
||||
"mv bin/busybox busybox",
|
||||
"rm -rf bin *.img update-binary");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Boolean result) {
|
||||
if (result) {
|
||||
mList.add("");
|
||||
mList.add("*********************************");
|
||||
mList.add(" Patched Boot Image is placed in ");
|
||||
mList.add(" " + dest + " ");
|
||||
mList.add("*********************************");
|
||||
}
|
||||
super.onPostExecute(result);
|
||||
}
|
||||
}
|
@ -94,12 +94,15 @@ public class ProcessRepoZip extends ParallelTask<Void, Void, Boolean> {
|
||||
progressDialog.dismiss();
|
||||
if (result) {
|
||||
if (Shell.rootAccess() && mInstall) {
|
||||
activity.startActivity(new Intent(activity, FlashActivity.class).setData(mUri));
|
||||
Intent intent = new Intent(getActivity(), FlashActivity.class);
|
||||
intent.setData(mUri).putExtra(FlashActivity.SET_ACTION, FlashActivity.FLASH_ZIP);
|
||||
activity.startActivity(intent);
|
||||
} else {
|
||||
Utils.showUriSnack(activity, mUri);
|
||||
}
|
||||
} else {
|
||||
Utils.getMagiskManager(activity).toast(R.string.process_error, Toast.LENGTH_LONG);
|
||||
}
|
||||
super.onPostExecute(result);
|
||||
}
|
||||
}
|
||||
|
@ -156,34 +156,38 @@ public class ZipUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static void unzip(File file, File folder, String path) throws Exception {
|
||||
int count;
|
||||
FileOutputStream out;
|
||||
File dest;
|
||||
InputStream is;
|
||||
JarEntry entry;
|
||||
public static void unzip(File zip, File folder, String path, boolean junkPath) throws Exception {
|
||||
JarInputStream in = new JarInputStream(new FileInputStream(zip));
|
||||
unzip(in, folder, path, junkPath);
|
||||
in.close();
|
||||
}
|
||||
|
||||
public static void unzip(InputStream zip, File folder, String path, boolean junkPath) throws Exception {
|
||||
byte data[] = new byte[4096];
|
||||
try (JarFile zipfile = new JarFile(file)) {
|
||||
Enumeration<JarEntry> e = zipfile.entries();
|
||||
while(e.hasMoreElements()) {
|
||||
entry = e.nextElement();
|
||||
if (!entry.getName().contains(path) || entry.isDirectory()){
|
||||
try {
|
||||
JarInputStream zipfile = new JarInputStream(zip);
|
||||
JarEntry entry;
|
||||
while ((entry = zipfile.getNextJarEntry()) != null) {
|
||||
if (!entry.getName().startsWith(path) || entry.isDirectory()){
|
||||
// Ignore directories, only create files
|
||||
continue;
|
||||
}
|
||||
Logger.dev("ZipUtils: Extracting: " + entry);
|
||||
is = zipfile.getInputStream(entry);
|
||||
dest = new File(folder, entry.getName());
|
||||
if (dest.getParentFile().mkdirs()) {
|
||||
dest.createNewFile();
|
||||
String name;
|
||||
if (junkPath) {
|
||||
name = entry.getName().substring(entry.getName().lastIndexOf('/') + 1);
|
||||
} else {
|
||||
name = entry.getName();
|
||||
}
|
||||
out = new FileOutputStream(dest);
|
||||
while ((count = is.read(data)) != -1) {
|
||||
Logger.dev("ZipUtils: Extracting: " + entry);
|
||||
File dest = new File(folder, name);
|
||||
dest.getParentFile().mkdirs();
|
||||
FileOutputStream out = new FileOutputStream(dest);
|
||||
int count;
|
||||
while ((count = zipfile.read(data)) != -1) {
|
||||
out.write(data, 0, count);
|
||||
}
|
||||
out.flush();
|
||||
out.close();
|
||||
is.close();
|
||||
}
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
|
@ -138,6 +138,10 @@
|
||||
<string name="flashing">Flashing</string>
|
||||
<string name="hide_manager_toast">Hiding Magisk Manager…</string>
|
||||
<string name="hide_manager_fail_toast">Hide Magisk Manager failed…</string>
|
||||
<string name="download_zip_only">Download Zip Only</string>
|
||||
<string name="patch_boot_file">Patch Boot Image File</string>
|
||||
<string name="direct_install">Direct Install (Recommend)</string>
|
||||
<string name="select_method">Select Method</string>
|
||||
|
||||
<!--Settings Activity -->
|
||||
<string name="settings_general_category">General</string>
|
||||
|
Loading…
Reference in New Issue
Block a user