mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-24 10:35:26 +00:00
Add flashing screen
This commit is contained in:
parent
f4097a372b
commit
2ea046cd80
@ -1,8 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest
|
||||
package="com.topjohnwu.magisk"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="com.topjohnwu.magisk">
|
||||
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
@ -22,8 +21,7 @@
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:configChanges="orientation|screenSize"
|
||||
android:exported="true"/>
|
||||
|
||||
android:exported="true" />
|
||||
<activity
|
||||
android:name=".SplashActivity"
|
||||
android:configChanges="orientation|screenSize"
|
||||
@ -31,16 +29,22 @@
|
||||
android:theme="@style/SplashTheme">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".AboutActivity"
|
||||
android:theme="@style/AppTheme.Transparent"/>
|
||||
android:theme="@style/AppTheme.Transparent" />
|
||||
<activity
|
||||
android:name=".SettingsActivity"
|
||||
android:theme="@style/AppTheme.Transparent" />
|
||||
<activity
|
||||
android:name=".FlashActivity"
|
||||
android:screenOrientation="nosensor"
|
||||
android:configChanges="keyboardHidden|orientation|screenSize"
|
||||
android:theme="@style/AppTheme.Transparent" />
|
||||
|
||||
<activity
|
||||
android:name=".superuser.RequestActivity"
|
||||
android:excludeFromRecents="true"
|
||||
@ -54,29 +58,26 @@
|
||||
android:theme="@style/SuRequest" />
|
||||
|
||||
<receiver android:name=".superuser.SuReceiver" />
|
||||
|
||||
<receiver android:name=".receivers.BootReceiver">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<receiver android:name=".receivers.PackageReceiver">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.PACKAGE_REPLACED" />
|
||||
<action android:name="android.intent.action.PACKAGE_FULLY_REMOVED" />
|
||||
|
||||
<data android:scheme="package" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<receiver android:name=".receivers.ManagerUpdate" />
|
||||
|
||||
<service android:name=".services.OnBootIntentService" />
|
||||
|
||||
<service
|
||||
android:name=".services.UpdateCheckService"
|
||||
android:permission="android.permission.BIND_JOB_SERVICE"
|
||||
android:exported="true" />
|
||||
android:exported="true"
|
||||
android:permission="android.permission.BIND_JOB_SERVICE" />
|
||||
|
||||
<provider
|
||||
android:name="android.support.v4.content.FileProvider"
|
||||
@ -94,4 +95,4 @@
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
</manifest>
|
98
app/src/main/java/com/topjohnwu/magisk/FlashActivity.java
Normal file
98
app/src/main/java/com/topjohnwu/magisk/FlashActivity.java
Normal file
@ -0,0 +1,98 @@
|
||||
package com.topjohnwu.magisk;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.topjohnwu.magisk.asyncs.FlashZip;
|
||||
import com.topjohnwu.magisk.components.Activity;
|
||||
import com.topjohnwu.magisk.utils.AdaptiveList;
|
||||
import com.topjohnwu.magisk.utils.Shell;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
|
||||
public class FlashActivity extends Activity {
|
||||
|
||||
@BindView(R.id.toolbar) Toolbar toolbar;
|
||||
@BindView(R.id.flash_logs) RecyclerView flashLogs;
|
||||
@BindView(R.id.button_panel) LinearLayout buttonPanel;
|
||||
|
||||
private AdaptiveList<String> rootShellOutput;
|
||||
|
||||
@OnClick(R.id.no_thanks)
|
||||
public void dismiss() {
|
||||
finish();
|
||||
}
|
||||
|
||||
@OnClick(R.id.reboot)
|
||||
public void reboot() {
|
||||
Shell.getRootShell(this).su_raw("reboot");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_flash);
|
||||
ButterKnife.bind(this);
|
||||
rootShellOutput = new AdaptiveList<>(flashLogs);
|
||||
setSupportActionBar(toolbar);
|
||||
ActionBar ab = getSupportActionBar();
|
||||
if (ab != null) {
|
||||
ab.setTitle(R.string.flashing);
|
||||
}
|
||||
setFloating();
|
||||
|
||||
flashLogs.setAdapter(new FlashLogAdapter());
|
||||
|
||||
// We must receive a Uri of the target zip
|
||||
Uri uri = getIntent().getData();
|
||||
|
||||
new FlashZip(this, uri, rootShellOutput)
|
||||
.setCallBack(() -> buttonPanel.setVisibility(View.VISIBLE))
|
||||
.exec();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
// Prevent user accidentally press back button
|
||||
}
|
||||
|
||||
private class FlashLogAdapter extends RecyclerView.Adapter<ViewHolder> {
|
||||
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.list_item_flashlog, parent, false);
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(ViewHolder holder, int position) {
|
||||
holder.text.setText(rootShellOutput.get(position));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return rootShellOutput.size();
|
||||
}
|
||||
}
|
||||
|
||||
public class ViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
@BindView(R.id.textView) TextView text;
|
||||
|
||||
public ViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
ButterKnife.bind(this, itemView);
|
||||
}
|
||||
}
|
||||
}
|
@ -26,7 +26,7 @@ import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.topjohnwu.magisk.asyncs.CheckUpdates;
|
||||
import com.topjohnwu.magisk.asyncs.ProcessMagiskZip;
|
||||
import com.topjohnwu.magisk.asyncs.ParallelTask;
|
||||
import com.topjohnwu.magisk.components.AlertDialogBuilder;
|
||||
import com.topjohnwu.magisk.components.Fragment;
|
||||
import com.topjohnwu.magisk.components.SnackbarMaker;
|
||||
@ -144,7 +144,13 @@ public class MagiskFragment extends Fragment
|
||||
|
||||
@Override
|
||||
public void onDownloadDone(Uri uri, Context context) {
|
||||
new ProcessMagiskZip(getActivity(), uri, boot, enc, verity).exec();
|
||||
if (Shell.rootAccess()) {
|
||||
new SetInstallFlags(boot, enc, verity)
|
||||
.setCallBack(() -> startActivity(new Intent(context, FlashActivity.class).setData(uri)))
|
||||
.exec(context);
|
||||
} else {
|
||||
Utils.showUriSnack(getActivity(), uri);
|
||||
}
|
||||
}
|
||||
},
|
||||
magiskManager.magiskLink,
|
||||
@ -160,6 +166,28 @@ public class MagiskFragment extends Fragment
|
||||
.show();
|
||||
}
|
||||
|
||||
private static class SetInstallFlags extends ParallelTask<Context, Void, Void> {
|
||||
|
||||
private String boot;
|
||||
private boolean enc, verity;
|
||||
|
||||
SetInstallFlags(String boot, boolean enc, boolean verity) {
|
||||
this.boot = boot;
|
||||
this.enc = enc;
|
||||
this.verity = verity;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Context... contexts) {
|
||||
Shell.getRootShell(contexts[0]).su_raw("rm -f /dev/.magisk",
|
||||
(boot != null) ? "echo \"BOOTIMAGE=" + boot + "\" >> /dev/.magisk" : "",
|
||||
"echo \"KEEPFORCEENCRYPT=" + String.valueOf(enc) + "\" >> /dev/.magisk",
|
||||
"echo \"KEEPVERITY=" + String.valueOf(verity) + "\" >> /dev/.magisk"
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@OnClick(R.id.uninstall_button)
|
||||
public void uninstall() {
|
||||
new AlertDialogBuilder(getActivity())
|
||||
|
@ -2,7 +2,6 @@ package com.topjohnwu.magisk;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
@ -14,13 +13,11 @@ import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.topjohnwu.magisk.adapters.ModulesAdapter;
|
||||
import com.topjohnwu.magisk.asyncs.FlashZip;
|
||||
import com.topjohnwu.magisk.asyncs.LoadModules;
|
||||
import com.topjohnwu.magisk.components.Fragment;
|
||||
import com.topjohnwu.magisk.module.Module;
|
||||
import com.topjohnwu.magisk.utils.CallbackEvent;
|
||||
import com.topjohnwu.magisk.utils.Logger;
|
||||
import com.topjohnwu.magisk.utils.Shell;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -87,8 +84,9 @@ public class ModulesFragment extends Fragment implements CallbackEvent.Listener<
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (requestCode == FETCH_ZIP_CODE && resultCode == Activity.RESULT_OK && data != null) {
|
||||
// Get the URI of the selected file
|
||||
final Uri uri = data.getData();
|
||||
new FlashZip(getActivity(), uri).exec();
|
||||
Intent intent = new Intent(getActivity(), FlashActivity.class);
|
||||
intent.setData(data.getData()).putExtra("ACTION", "flash");
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -162,14 +162,14 @@ public class SettingsActivity extends Activity {
|
||||
new AlertDialogBuilder(getActivity())
|
||||
.setTitle(R.string.no_magisksu_title)
|
||||
.setMessage(R.string.no_magisksu_msg)
|
||||
.setPositiveButton(R.string.understand, (dialog, which) -> new MagiskHide().enable())
|
||||
.setPositiveButton(R.string.understand, (dialog, which) -> new MagiskHide(getActivity()).enable())
|
||||
.setCancelable(false)
|
||||
.show();
|
||||
} else {
|
||||
new MagiskHide().enable();
|
||||
new MagiskHide(getActivity()).enable();
|
||||
}
|
||||
} else {
|
||||
new MagiskHide().disable();
|
||||
new MagiskHide(getActivity()).disable();
|
||||
}
|
||||
break;
|
||||
case "hosts":
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.topjohnwu.magisk.adapters;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.support.design.widget.Snackbar;
|
||||
@ -86,10 +87,10 @@ public class ApplicationAdapter extends RecyclerView.Adapter<ApplicationAdapter.
|
||||
holder.checkBox.setChecked(mHideList.contains(info.packageName));
|
||||
holder.checkBox.setOnCheckedChangeListener((v, isChecked) -> {
|
||||
if (isChecked) {
|
||||
new MagiskHide().add(info.packageName);
|
||||
new MagiskHide((Activity) holder.itemView.getContext()).add(info.packageName);
|
||||
mHideList.add(info.packageName);
|
||||
} else {
|
||||
new MagiskHide().rm(info.packageName);
|
||||
new MagiskHide((Activity) holder.itemView.getContext()).rm(info.packageName);
|
||||
mHideList.remove(info.packageName);
|
||||
}
|
||||
});
|
||||
|
@ -1,14 +1,12 @@
|
||||
package com.topjohnwu.magisk.asyncs;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ProgressDialog;
|
||||
import android.net.Uri;
|
||||
import android.widget.Toast;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.topjohnwu.magisk.MagiskManager;
|
||||
import com.topjohnwu.magisk.R;
|
||||
import com.topjohnwu.magisk.components.AlertDialogBuilder;
|
||||
import com.topjohnwu.magisk.utils.Logger;
|
||||
import com.topjohnwu.magisk.utils.AdaptiveList;
|
||||
import com.topjohnwu.magisk.utils.Utils;
|
||||
import com.topjohnwu.magisk.utils.ZipUtils;
|
||||
|
||||
@ -26,11 +24,12 @@ public class FlashZip extends ParallelTask<Void, String, Integer> {
|
||||
private File mCachedFile, mScriptFile, mCheckFile;
|
||||
|
||||
private String mFilename;
|
||||
private ProgressDialog progress;
|
||||
private AdaptiveList<String> mList;
|
||||
|
||||
public FlashZip(Activity context, Uri uri) {
|
||||
public FlashZip(Activity context, Uri uri, AdaptiveList<String> list) {
|
||||
super(context);
|
||||
mUri = uri;
|
||||
mList = list;
|
||||
|
||||
mCachedFile = new File(magiskManager.getCacheDir(), "install.zip");
|
||||
mScriptFile = new File(magiskManager.getCacheDir(), "/META-INF/com/google/android/update-binary");
|
||||
@ -40,97 +39,77 @@ public class FlashZip extends ParallelTask<Void, String, Integer> {
|
||||
mFilename = Utils.getNameFromUri(magiskManager, mUri);
|
||||
}
|
||||
|
||||
private void copyToCache() throws Throwable {
|
||||
publishProgress(magiskManager.getString(R.string.copying_msg));
|
||||
private void copyToCache() throws Exception {
|
||||
mList.add(magiskManager.getString(R.string.copying_msg));
|
||||
|
||||
if (mCachedFile.exists() && !mCachedFile.delete()) {
|
||||
Logger.error("FlashZip: Error while deleting already existing file");
|
||||
throw new IOException();
|
||||
}
|
||||
mCachedFile.delete();
|
||||
try (
|
||||
InputStream in = magiskManager.getContentResolver().openInputStream(mUri);
|
||||
OutputStream outputStream = new FileOutputStream(mCachedFile)
|
||||
InputStream in = magiskManager.getContentResolver().openInputStream(mUri);
|
||||
OutputStream outputStream = new FileOutputStream(mCachedFile)
|
||||
) {
|
||||
byte buffer[] = new byte[1024];
|
||||
int length;
|
||||
if (in == null) throw new FileNotFoundException();
|
||||
while ((length = in.read(buffer)) > 0)
|
||||
outputStream.write(buffer, 0, length);
|
||||
|
||||
Logger.dev("FlashZip: File created successfully - " + mCachedFile.getPath());
|
||||
} catch (FileNotFoundException e) {
|
||||
Logger.error("FlashZip: Invalid Uri");
|
||||
mList.add("! Invalid Uri");
|
||||
throw e;
|
||||
} catch (IOException e) {
|
||||
Logger.error("FlashZip: Error in creating file");
|
||||
mList.add("! Cannot copy to cache");
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean unzipAndCheck() throws Exception {
|
||||
ZipUtils.unzip(mCachedFile, mCachedFile.getParentFile(), "META-INF/com/google/android");
|
||||
List<String> ret;
|
||||
ret = Utils.readFile(magiskManager.rootShell, mCheckFile.getPath());
|
||||
List<String> ret = Utils.readFile(magiskManager.rootShell, mCheckFile.getPath());
|
||||
return Utils.isValidShellResponse(ret) && ret.get(0).contains("#MAGISK");
|
||||
}
|
||||
|
||||
private int cleanup(int ret) {
|
||||
magiskManager.rootShell.su_raw(
|
||||
"rm -rf " + mCachedFile.getParent() + "/*",
|
||||
"rm -rf " + MagiskManager.TMP_FOLDER_PATH
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
progress = new ProgressDialog(activity);
|
||||
progress.setTitle(R.string.zip_install_progress_title);
|
||||
progress.show();
|
||||
// UI updates must run in the UI thread
|
||||
mList.setCallback(this::publishProgress);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onProgressUpdate(String... values) {
|
||||
progress.setMessage(values[0]);
|
||||
mList.updateView();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Integer doInBackground(Void... voids) {
|
||||
Logger.dev("FlashZip Running... " + mFilename);
|
||||
List<String> ret;
|
||||
try {
|
||||
copyToCache();
|
||||
if (!unzipAndCheck()) return cleanup(0);
|
||||
publishProgress(magiskManager.getString(R.string.zip_install_progress_msg, mFilename));
|
||||
ret = magiskManager.rootShell.su(
|
||||
"BOOTMODE=true sh " + mScriptFile + " dummy 1 " + mCachedFile,
|
||||
"if [ $? -eq 0 ]; then echo true; else echo false; fi"
|
||||
if (!unzipAndCheck()) return 0;
|
||||
mList.add(magiskManager.getString(R.string.zip_install_progress_msg, mFilename));
|
||||
magiskManager.rootShell.su(mList,
|
||||
"BOOTMODE=true sh " + mScriptFile + " dummy 1 " + mCachedFile +
|
||||
" && echo 'Success!' || echo 'Failed!'"
|
||||
);
|
||||
if (!Utils.isValidShellResponse(ret)) return -1;
|
||||
Logger.dev("FlashZip: Console log:");
|
||||
for (String line : ret) {
|
||||
Logger.dev(line);
|
||||
}
|
||||
if (Boolean.parseBoolean(ret.get(ret.size() - 1)))
|
||||
return cleanup(1);
|
||||
|
||||
} catch (Throwable e) {
|
||||
if (TextUtils.equals(mList.get(mList.size() - 1), "Success!"))
|
||||
return 1;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return cleanup(-1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// -1 = error, manual install; 0 = invalid zip; 1 = success
|
||||
@Override
|
||||
protected void onPostExecute(Integer result) {
|
||||
progress.dismiss();
|
||||
magiskManager.rootShell.su_raw(
|
||||
"rm -rf " + mCachedFile.getParent() + "/*",
|
||||
"rm -rf " + MagiskManager.TMP_FOLDER_PATH
|
||||
);
|
||||
switch (result) {
|
||||
case -1:
|
||||
Toast.makeText(magiskManager, magiskManager.getString(R.string.install_error), Toast.LENGTH_LONG).show();
|
||||
mList.add(magiskManager.getString(R.string.install_error));
|
||||
Utils.showUriSnack(activity, mUri);
|
||||
break;
|
||||
case 0:
|
||||
Toast.makeText(magiskManager, magiskManager.getString(R.string.invalid_zip), Toast.LENGTH_LONG).show();
|
||||
mList.add(magiskManager.getString(R.string.invalid_zip));
|
||||
break;
|
||||
case 1:
|
||||
onSuccess();
|
||||
@ -140,14 +119,6 @@ public class FlashZip extends ParallelTask<Void, String, Integer> {
|
||||
}
|
||||
|
||||
protected void onSuccess() {
|
||||
magiskManager.updateCheckDone.trigger();
|
||||
new LoadModules(activity).exec();
|
||||
|
||||
new AlertDialogBuilder(activity)
|
||||
.setTitle(R.string.reboot_title)
|
||||
.setMessage(R.string.reboot_msg)
|
||||
.setPositiveButton(R.string.reboot, (dialogInterface, i) -> magiskManager.rootShell.su_raw("reboot"))
|
||||
.setNegativeButton(R.string.no_thanks, null)
|
||||
.show();
|
||||
}
|
||||
}
|
||||
|
@ -8,8 +8,6 @@ public class MagiskHide extends ParallelTask<Object, Void, Void> {
|
||||
|
||||
private boolean isList = false;
|
||||
|
||||
public MagiskHide() {}
|
||||
|
||||
public MagiskHide(Activity context) {
|
||||
super(context);
|
||||
}
|
||||
|
@ -1,56 +0,0 @@
|
||||
package com.topjohnwu.magisk.asyncs;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ProgressDialog;
|
||||
import android.net.Uri;
|
||||
|
||||
import com.topjohnwu.magisk.R;
|
||||
import com.topjohnwu.magisk.utils.Shell;
|
||||
import com.topjohnwu.magisk.utils.Utils;
|
||||
|
||||
public class ProcessMagiskZip extends ParallelTask<Void, Void, Boolean> {
|
||||
|
||||
private Uri mUri;
|
||||
private ProgressDialog progressDialog;
|
||||
private String mBoot;
|
||||
private boolean mEnc, mVerity;
|
||||
|
||||
public ProcessMagiskZip(Activity context, Uri uri, String boot, boolean enc, boolean verity) {
|
||||
super(context);
|
||||
mUri = uri;
|
||||
mBoot = boot;
|
||||
mEnc = enc;
|
||||
mVerity = verity;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
progressDialog = ProgressDialog.show(activity,
|
||||
activity.getString(R.string.zip_process_title),
|
||||
activity.getString(R.string.zip_unzip_msg));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Boolean doInBackground(Void... params) {
|
||||
if (Shell.rootAccess()) {
|
||||
magiskManager.rootShell.su_raw("rm -f /dev/.magisk",
|
||||
(mBoot != null) ? "echo \"BOOTIMAGE=" + mBoot + "\" >> /dev/.magisk" : "",
|
||||
"echo \"KEEPFORCEENCRYPT=" + String.valueOf(mEnc) + "\" >> /dev/.magisk",
|
||||
"echo \"KEEPVERITY=" + String.valueOf(mVerity) + "\" >> /dev/.magisk"
|
||||
);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Boolean result) {
|
||||
progressDialog.dismiss();
|
||||
if (result) {
|
||||
new FlashZip(activity, mUri).exec();
|
||||
} else {
|
||||
Utils.showUriSnack(activity, mUri);
|
||||
}
|
||||
super.onPostExecute(result);
|
||||
}
|
||||
}
|
@ -2,9 +2,11 @@ package com.topjohnwu.magisk.asyncs;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.topjohnwu.magisk.FlashActivity;
|
||||
import com.topjohnwu.magisk.R;
|
||||
import com.topjohnwu.magisk.utils.Logger;
|
||||
import com.topjohnwu.magisk.utils.Shell;
|
||||
@ -85,13 +87,12 @@ public class ProcessRepoZip extends ParallelTask<Void, Void, Boolean> {
|
||||
progressDialog.dismiss();
|
||||
if (result) {
|
||||
if (Shell.rootAccess() && mInstall) {
|
||||
new FlashZip(activity, mUri).exec();
|
||||
magiskManager.startActivity(new Intent(magiskManager, FlashActivity.class).setData(mUri));
|
||||
} else {
|
||||
Utils.showUriSnack(activity, mUri);
|
||||
}
|
||||
|
||||
} else {
|
||||
Toast.makeText(activity, R.string.process_error, Toast.LENGTH_LONG).show();
|
||||
magiskManager.toast(R.string.process_error, Toast.LENGTH_LONG);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,36 @@
|
||||
package com.topjohnwu.magisk.utils;
|
||||
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class AdaptiveList<E> extends ArrayList<E> {
|
||||
|
||||
private Runnable callback;
|
||||
private RecyclerView mView;
|
||||
|
||||
public AdaptiveList(RecyclerView v) {
|
||||
mView = v;
|
||||
}
|
||||
|
||||
public void updateView() {
|
||||
mView.getAdapter().notifyDataSetChanged();
|
||||
mView.scrollToPosition(mView.getAdapter().getItemCount() - 1);
|
||||
}
|
||||
|
||||
public void setCallback(Runnable cb) {
|
||||
callback = cb;
|
||||
}
|
||||
|
||||
public boolean add(E e) {
|
||||
boolean ret = super.add(e);
|
||||
if (ret) {
|
||||
if (callback == null) {
|
||||
updateView();
|
||||
} else {
|
||||
callback.run();
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
@ -44,19 +44,19 @@ public class Utils {
|
||||
private static final int APK_UPDATE_NOTIFICATION_ID = 2;
|
||||
|
||||
public static boolean itemExist(Shell shell, String path) {
|
||||
String command = "if [ -e " + path + " ]; then echo true; else echo false; fi";
|
||||
String command = "[ -e " + path + " ] && echo true || echo false";
|
||||
List<String> ret = shell.su(command);
|
||||
return isValidShellResponse(ret) && Boolean.parseBoolean(ret.get(0));
|
||||
}
|
||||
|
||||
public static void createFile(Shell shell, String path) {
|
||||
String folder = path.substring(0, path.lastIndexOf('/'));
|
||||
String command = "mkdir -p " + folder + " 2>/dev/null; touch " + path + " 2>/dev/null; if [ -f \"" + path + "\" ]; then echo true; else echo false; fi";
|
||||
String command = "mkdir -p " + folder + " 2>/dev/null; touch " + path + " 2>/dev/null;";
|
||||
shell.su_raw(command);
|
||||
}
|
||||
|
||||
public static void removeItem(Shell shell, String path) {
|
||||
String command = "rm -rf " + path + " 2>/dev/null; if [ -e " + path + " ]; then echo false; else echo true; fi";
|
||||
String command = "rm -rf " + path + " 2>/dev/null";
|
||||
shell.su_raw(command);
|
||||
}
|
||||
|
||||
|
56
app/src/main/res/layout/activity_flash.xml
Normal file
56
app/src/main/res/layout/activity_flash.xml
Normal file
@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="vertical"
|
||||
android:background="@android:color/black"
|
||||
tools:context="com.topjohnwu.magisk.FlashActivity">
|
||||
|
||||
<include layout="@layout/toolbar"/>
|
||||
|
||||
<HorizontalScrollView
|
||||
android:layout_weight="1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp">
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/flash_logs"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
app:layoutManager="android.support.v7.widget.LinearLayoutManager">
|
||||
|
||||
</android.support.v7.widget.RecyclerView>
|
||||
|
||||
</HorizontalScrollView>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/button_panel"
|
||||
style="?android:buttonStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:background="@android:color/darker_gray"
|
||||
android:orientation="horizontal"
|
||||
android:visibility="gone">
|
||||
|
||||
<Button
|
||||
android:id="@+id/no_thanks"
|
||||
style="?android:borderlessButtonStyle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/close" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/reboot"
|
||||
style="?android:borderlessButtonStyle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/reboot" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
9
app/src/main/res/layout/list_item_flashlog.xml
Normal file
9
app/src/main/res/layout/list_item_flashlog.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TextView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/textView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="monospace"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="10sp" />
|
@ -133,6 +133,7 @@
|
||||
<string name="manager_update_title">New Magisk Manager Update Available!</string>
|
||||
<string name="manager_download_install">Press to download and install</string>
|
||||
<string name="magisk_updates">Magisk Updates</string>
|
||||
<string name="flashing">Flashing</string>
|
||||
|
||||
<!--Settings Activity -->
|
||||
<string name="settings_general_category">General</string>
|
||||
|
Loading…
Reference in New Issue
Block a user