mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-28 04:25:27 +00:00
Fully support dtbo.img patching
This commit is contained in:
parent
4ac83cfded
commit
826543a291
@ -73,6 +73,7 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
<receiver android:name=".receivers.ManagerUpdate" />
|
<receiver android:name=".receivers.ManagerUpdate" />
|
||||||
|
<receiver android:name=".receivers.RebootReceiver" />
|
||||||
|
|
||||||
<service android:name=".services.OnBootIntentService" />
|
<service android:name=".services.OnBootIntentService" />
|
||||||
<service
|
<service
|
||||||
|
@ -5,20 +5,16 @@ import android.content.Context;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.annotation.StringRes;
|
import android.support.annotation.StringRes;
|
||||||
import android.support.design.widget.Snackbar;
|
|
||||||
import android.support.v4.widget.SwipeRefreshLayout;
|
import android.support.v4.widget.SwipeRefreshLayout;
|
||||||
import android.support.v7.widget.CardView;
|
import android.support.v7.widget.CardView;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.ArrayAdapter;
|
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.CheckBox;
|
import android.widget.CheckBox;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.RelativeLayout;
|
import android.widget.RelativeLayout;
|
||||||
import android.widget.Spinner;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.topjohnwu.magisk.asyncs.CheckSafetyNet;
|
import com.topjohnwu.magisk.asyncs.CheckSafetyNet;
|
||||||
@ -26,15 +22,11 @@ import com.topjohnwu.magisk.asyncs.CheckUpdates;
|
|||||||
import com.topjohnwu.magisk.components.AlertDialogBuilder;
|
import com.topjohnwu.magisk.components.AlertDialogBuilder;
|
||||||
import com.topjohnwu.magisk.components.ExpandableView;
|
import com.topjohnwu.magisk.components.ExpandableView;
|
||||||
import com.topjohnwu.magisk.components.Fragment;
|
import com.topjohnwu.magisk.components.Fragment;
|
||||||
import com.topjohnwu.magisk.components.SnackbarMaker;
|
|
||||||
import com.topjohnwu.magisk.utils.Shell;
|
import com.topjohnwu.magisk.utils.Shell;
|
||||||
import com.topjohnwu.magisk.utils.ShowUI;
|
import com.topjohnwu.magisk.utils.ShowUI;
|
||||||
import com.topjohnwu.magisk.utils.Topic;
|
import com.topjohnwu.magisk.utils.Topic;
|
||||||
import com.topjohnwu.magisk.utils.Utils;
|
import com.topjohnwu.magisk.utils.Utils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import butterknife.BindColor;
|
import butterknife.BindColor;
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
@ -77,9 +69,6 @@ public class MagiskFragment extends Fragment
|
|||||||
@BindView(R.id.basic_status_icon) ImageView basicStatusIcon;
|
@BindView(R.id.basic_status_icon) ImageView basicStatusIcon;
|
||||||
@BindView(R.id.basic_status) TextView basicStatusText;
|
@BindView(R.id.basic_status) TextView basicStatusText;
|
||||||
|
|
||||||
@BindView(R.id.bootimage_card) CardView bootImageCard;
|
|
||||||
@BindView(R.id.block_spinner) Spinner spinner;
|
|
||||||
@BindView(R.id.detect_bootimage) Button detectButton;
|
|
||||||
@BindView(R.id.install_option_card) CardView installOptionCard;
|
@BindView(R.id.install_option_card) CardView installOptionCard;
|
||||||
@BindView(R.id.keep_force_enc) CheckBox keepEncChkbox;
|
@BindView(R.id.keep_force_enc) CheckBox keepEncChkbox;
|
||||||
@BindView(R.id.keep_verity) CheckBox keepVerityChkbox;
|
@BindView(R.id.keep_verity) CheckBox keepVerityChkbox;
|
||||||
@ -123,18 +112,18 @@ public class MagiskFragment extends Fragment
|
|||||||
|
|
||||||
// Show Manager update first
|
// Show Manager update first
|
||||||
if (mm.remoteManagerVersionCode > BuildConfig.VERSION_CODE) {
|
if (mm.remoteManagerVersionCode > BuildConfig.VERSION_CODE) {
|
||||||
ShowUI.showManagerInstallDialog(getActivity());
|
ShowUI.managerInstallDialog(getActivity());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
((NotificationManager) mm.getSystemService(Context.NOTIFICATION_SERVICE)).cancelAll();
|
((NotificationManager) mm.getSystemService(Context.NOTIFICATION_SERVICE)).cancelAll();
|
||||||
ShowUI.showMagiskInstallDialog(this,
|
ShowUI.magiskInstallDialog(getActivity(),
|
||||||
keepEncChkbox.isChecked(), keepVerityChkbox.isChecked());
|
keepEncChkbox.isChecked(), keepVerityChkbox.isChecked());
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClick(R.id.uninstall_button)
|
@OnClick(R.id.uninstall_button)
|
||||||
void uninstall() {
|
void uninstall() {
|
||||||
ShowUI.showUninstallDialog(this);
|
ShowUI.uninstallDialog(getActivity());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@ -207,25 +196,6 @@ public class MagiskFragment extends Fragment
|
|||||||
return expandableContainer;
|
return expandableContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSelectedBootImage() {
|
|
||||||
if (Shell.rootAccess()) {
|
|
||||||
if (mm.bootBlock != null) {
|
|
||||||
return mm.bootBlock;
|
|
||||||
} else {
|
|
||||||
int idx = spinner.getSelectedItemPosition();
|
|
||||||
if (idx > 0) {
|
|
||||||
return mm.blockList.get(idx - 1);
|
|
||||||
} else {
|
|
||||||
SnackbarMaker.make(getActivity(),
|
|
||||||
R.string.manual_boot_image, Snackbar.LENGTH_LONG).show();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateUI() {
|
private void updateUI() {
|
||||||
((MainActivity) getActivity()).checkHideSection();
|
((MainActivity) getActivity()).checkHideSection();
|
||||||
|
|
||||||
@ -235,7 +205,6 @@ public class MagiskFragment extends Fragment
|
|||||||
|
|
||||||
magiskUpdate.setVisibility(hasNetwork ? View.VISIBLE : View.GONE);
|
magiskUpdate.setVisibility(hasNetwork ? View.VISIBLE : View.GONE);
|
||||||
safetyNetCard.setVisibility(hasNetwork ? View.VISIBLE : View.GONE);
|
safetyNetCard.setVisibility(hasNetwork ? View.VISIBLE : View.GONE);
|
||||||
bootImageCard.setVisibility(hasNetwork && hasRoot ? View.VISIBLE : View.GONE);
|
|
||||||
installOptionCard.setVisibility(hasNetwork ? View.VISIBLE : View.GONE);
|
installOptionCard.setVisibility(hasNetwork ? View.VISIBLE : View.GONE);
|
||||||
uninstallButton.setVisibility(isUpToDate && hasRoot ? View.VISIBLE : View.GONE);
|
uninstallButton.setVisibility(isUpToDate && hasRoot ? View.VISIBLE : View.GONE);
|
||||||
|
|
||||||
@ -253,20 +222,6 @@ public class MagiskFragment extends Fragment
|
|||||||
|
|
||||||
magiskStatusIcon.setImageResource(image);
|
magiskStatusIcon.setImageResource(image);
|
||||||
magiskStatusIcon.setColorFilter(color);
|
magiskStatusIcon.setColorFilter(color);
|
||||||
|
|
||||||
List<String> items = new ArrayList<>();
|
|
||||||
if (mm.bootBlock != null) {
|
|
||||||
items.add(getString(R.string.auto_detect, mm.bootBlock));
|
|
||||||
spinner.setEnabled(false);
|
|
||||||
} else {
|
|
||||||
items.add(getString(R.string.cannot_auto_detect));
|
|
||||||
if (mm.blockList != null)
|
|
||||||
items.addAll(mm.blockList);
|
|
||||||
}
|
|
||||||
ArrayAdapter<String> adapter = new ArrayAdapter<>(getActivity(),
|
|
||||||
android.R.layout.simple_spinner_item, items);
|
|
||||||
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
|
||||||
spinner.setAdapter(adapter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateCheckUI() {
|
private void updateCheckUI() {
|
||||||
|
@ -55,7 +55,6 @@ public class MagiskManager extends Application {
|
|||||||
|
|
||||||
// Data
|
// Data
|
||||||
public Map<String, Module> moduleMap;
|
public Map<String, Module> moduleMap;
|
||||||
public List<String> blockList;
|
|
||||||
public List<Locale> locales;
|
public List<Locale> locales;
|
||||||
|
|
||||||
// Configurations
|
// Configurations
|
||||||
|
@ -21,8 +21,6 @@ import com.topjohnwu.magisk.utils.Const;
|
|||||||
import com.topjohnwu.magisk.utils.Shell;
|
import com.topjohnwu.magisk.utils.Shell;
|
||||||
import com.topjohnwu.magisk.utils.Utils;
|
import com.topjohnwu.magisk.utils.Utils;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class SplashActivity extends Activity {
|
public class SplashActivity extends Activity {
|
||||||
@ -57,27 +55,10 @@ public class SplashActivity extends Activity {
|
|||||||
|
|
||||||
// Magisk working as expected
|
// Magisk working as expected
|
||||||
if (Shell.rootAccess() && mm.magiskVersionCode > 0) {
|
if (Shell.rootAccess() && mm.magiskVersionCode > 0) {
|
||||||
// Load utility shell scripts
|
|
||||||
try (InputStream in = getAssets().open(Const.UTIL_FUNCTIONS)) {
|
|
||||||
Shell.getShell().loadInputStream(in);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Root shell initialization
|
|
||||||
Shell.su_raw(
|
|
||||||
"export PATH=" + Const.BUSYBOXPATH + ":$PATH",
|
|
||||||
"mount_partitions",
|
|
||||||
"BOOTIMAGE=",
|
|
||||||
"find_boot_image",
|
|
||||||
"migrate_boot_backup"
|
|
||||||
);
|
|
||||||
|
|
||||||
List<String> ret = Shell.su("echo \"$BOOTIMAGE\"");
|
List<String> ret = Shell.su("echo \"$BOOTIMAGE\"");
|
||||||
if (Utils.isValidShellResponse(ret)) {
|
if (Utils.isValidShellResponse(ret)) {
|
||||||
mm.bootBlock = ret.get(0);
|
mm.bootBlock = ret.get(0);
|
||||||
} else {
|
|
||||||
mm.blockList = Shell.su("find /dev/block -type b | grep -vE 'dm|ram|loop'");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup suDB
|
// Setup suDB
|
||||||
@ -105,6 +86,9 @@ public class SplashActivity extends Activity {
|
|||||||
|
|
||||||
// Fire asynctasks
|
// Fire asynctasks
|
||||||
loadModuleTask.exec();
|
loadModuleTask.exec();
|
||||||
|
|
||||||
|
// Check dtbo status
|
||||||
|
Utils.patchDTBO();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write back default values
|
// Write back default values
|
||||||
|
@ -55,9 +55,9 @@ public class CheckUpdates extends ParallelTask<Void, Void, Void> {
|
|||||||
MagiskManager mm = MagiskManager.get();
|
MagiskManager mm = MagiskManager.get();
|
||||||
if (showNotification && mm.updateNotification) {
|
if (showNotification && mm.updateNotification) {
|
||||||
if (BuildConfig.VERSION_CODE < mm.remoteManagerVersionCode) {
|
if (BuildConfig.VERSION_CODE < mm.remoteManagerVersionCode) {
|
||||||
ShowUI.showManagerUpdateNotification();
|
ShowUI.managerUpdateNotification();
|
||||||
} else if (mm.magiskVersionCode < mm.remoteMagiskVersionCode) {
|
} else if (mm.magiskVersionCode < mm.remoteMagiskVersionCode) {
|
||||||
ShowUI.showMagiskUpdateNotification();
|
ShowUI.magiskUpdateNotification();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mm.updateCheckDone.publish();
|
mm.updateCheckDone.publish();
|
||||||
|
@ -226,13 +226,15 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
|||||||
mList.add("*********************************");
|
mList.add("*********************************");
|
||||||
break;
|
break;
|
||||||
case DIRECT_MODE:
|
case DIRECT_MODE:
|
||||||
// Direct flash boot image
|
// Direct flash boot image and patch dtbo if possible
|
||||||
Shell.su(mList,
|
Shell.su(mList,
|
||||||
"rm -rf /data/magisk/*",
|
"rm -rf /data/magisk/*",
|
||||||
|
"mkdir -p /data/magisk 2>/dev/null",
|
||||||
"mv -f " + install + "/* /data/magisk",
|
"mv -f " + install + "/* /data/magisk",
|
||||||
"rm -rf " + install,
|
"rm -rf " + install,
|
||||||
"flash_boot_image " + patched_boot + " " + mBootLocation,
|
"flash_boot_image " + patched_boot + " " + mBootLocation,
|
||||||
"rm -rf " + patched_boot);
|
"rm -rf " + patched_boot,
|
||||||
|
"patch_dtbo_image");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
@ -11,30 +11,22 @@ import java.util.List;
|
|||||||
|
|
||||||
public class RestoreStockBoot extends ParallelTask<Void, Void, Boolean> {
|
public class RestoreStockBoot extends ParallelTask<Void, Void, Boolean> {
|
||||||
|
|
||||||
private String mBoot;
|
|
||||||
|
|
||||||
public RestoreStockBoot(String boot) {
|
|
||||||
mBoot = boot;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Boolean doInBackground(Void... voids) {
|
protected Boolean doInBackground(Void... voids) {
|
||||||
String sha1;
|
String sha1;
|
||||||
List<String> ret = Utils.readFile("/.backup/.sha1");
|
List<String> ret = Utils.readFile("/.backup/.sha1");
|
||||||
if (!Utils.isValidShellResponse(ret)) {
|
if (Utils.isValidShellResponse(ret)) {
|
||||||
|
sha1 = ret.get(0);
|
||||||
|
} else {
|
||||||
ret = Shell.su("cat /init.magisk.rc | grep STOCKSHA1");
|
ret = Shell.su("cat /init.magisk.rc | grep STOCKSHA1");
|
||||||
if (!Utils.isValidShellResponse(ret))
|
if (!Utils.isValidShellResponse(ret))
|
||||||
return false;
|
return false;
|
||||||
sha1 = ret.get(0).substring(ret.get(0).indexOf('=') + 1);
|
sha1 = ret.get(0).substring(ret.get(0).indexOf('=') + 1);
|
||||||
} else {
|
|
||||||
sha1 = ret.get(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String stock_boot = "/data/stock_boot_" + sha1 + ".img.gz";
|
ret = Shell.su("restore_imgs " + sha1 + " && echo true || echo false");
|
||||||
if (!Utils.itemExist(stock_boot))
|
|
||||||
return false;
|
return Utils.isValidShellResponse(ret) && Boolean.parseBoolean(ret.get(ret.size() - 1));
|
||||||
Shell.su_raw("flash_boot_image " + stock_boot + " " + mBoot);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.topjohnwu.magisk.components;
|
package com.topjohnwu.magisk.components;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.res.AssetManager;
|
import android.content.res.AssetManager;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
@ -20,6 +21,7 @@ public class Activity extends AppCompatActivity {
|
|||||||
|
|
||||||
private AssetManager mAssetManager = null;
|
private AssetManager mAssetManager = null;
|
||||||
private Resources mResources = null;
|
private Resources mResources = null;
|
||||||
|
private ActivityResultListener activityResultListener;
|
||||||
|
|
||||||
public Activity() {
|
public Activity() {
|
||||||
super();
|
super();
|
||||||
@ -83,6 +85,18 @@ public class Activity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
if (activityResultListener != null)
|
||||||
|
activityResultListener.onActivityResult(requestCode, resultCode, data);
|
||||||
|
activityResultListener = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startActivityForResult(Intent intent, int requestCode, ActivityResultListener listener) {
|
||||||
|
activityResultListener = listener;
|
||||||
|
super.startActivityForResult(intent, requestCode);
|
||||||
|
}
|
||||||
|
|
||||||
@Keep
|
@Keep
|
||||||
public void swapResources(String dexPath) {
|
public void swapResources(String dexPath) {
|
||||||
mAssetManager = Utils.getAssets(dexPath);
|
mAssetManager = Utils.getAssets(dexPath);
|
||||||
@ -99,4 +113,8 @@ public class Activity extends AppCompatActivity {
|
|||||||
mResources = null;
|
mResources = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface ActivityResultListener {
|
||||||
|
void onActivityResult(int requestCode, int resultCode, Intent data);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,11 @@
|
|||||||
package com.topjohnwu.magisk.components;
|
package com.topjohnwu.magisk.components;
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
|
|
||||||
import com.topjohnwu.magisk.MagiskManager;
|
import com.topjohnwu.magisk.MagiskManager;
|
||||||
import com.topjohnwu.magisk.utils.Topic;
|
import com.topjohnwu.magisk.utils.Topic;
|
||||||
import com.topjohnwu.magisk.utils.Utils;
|
import com.topjohnwu.magisk.utils.Utils;
|
||||||
|
|
||||||
public class Fragment extends android.support.v4.app.Fragment {
|
public class Fragment extends android.support.v4.app.Fragment {
|
||||||
|
|
||||||
private ActivityResultListener activityResultListener;
|
|
||||||
|
|
||||||
public MagiskManager getApplication() {
|
public MagiskManager getApplication() {
|
||||||
return Utils.getMagiskManager(getActivity());
|
return Utils.getMagiskManager(getActivity());
|
||||||
}
|
}
|
||||||
@ -29,20 +25,4 @@ public class Fragment extends android.support.v4.app.Fragment {
|
|||||||
}
|
}
|
||||||
super.onPause();
|
super.onPause();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
|
||||||
if (activityResultListener != null)
|
|
||||||
activityResultListener.onActivityResult(requestCode, resultCode, data);
|
|
||||||
activityResultListener = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void startActivityForResult(Intent intent, int requestCode, ActivityResultListener listener) {
|
|
||||||
activityResultListener = listener;
|
|
||||||
super.startActivityForResult(intent, requestCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface ActivityResultListener {
|
|
||||||
void onActivityResult(int requestCode, int resultCode, Intent data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -19,10 +19,7 @@ public class BootReceiver extends BroadcastReceiver {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
|
startIntentService(context);
|
||||||
// There is currently no need to start an IntentService onBoot
|
|
||||||
// startIntentService(context);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,14 @@
|
|||||||
|
package com.topjohnwu.magisk.receivers;
|
||||||
|
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
|
||||||
|
import com.topjohnwu.magisk.utils.Shell;
|
||||||
|
|
||||||
|
public class RebootReceiver extends BroadcastReceiver {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
Shell.su_raw("reboot");
|
||||||
|
}
|
||||||
|
}
|
@ -5,8 +5,11 @@ import android.content.Intent;
|
|||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.support.v4.app.NotificationCompat;
|
import android.support.v4.app.NotificationCompat;
|
||||||
|
|
||||||
|
import com.topjohnwu.magisk.MagiskManager;
|
||||||
import com.topjohnwu.magisk.R;
|
import com.topjohnwu.magisk.R;
|
||||||
import com.topjohnwu.magisk.utils.Const;
|
import com.topjohnwu.magisk.utils.Const;
|
||||||
|
import com.topjohnwu.magisk.utils.Shell;
|
||||||
|
import com.topjohnwu.magisk.utils.Utils;
|
||||||
|
|
||||||
public class OnBootIntentService extends IntentService {
|
public class OnBootIntentService extends IntentService {
|
||||||
|
|
||||||
@ -29,6 +32,17 @@ public class OnBootIntentService extends IntentService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onHandleIntent(Intent intent) {
|
protected void onHandleIntent(Intent intent) {
|
||||||
// Currently nothing to do
|
/* Pixel 2 (XL) devices will need to patch dtbo.img.
|
||||||
|
* However, that is not possible if Magisk is installed by
|
||||||
|
* patching boot image with Magisk Manager and fastboot flash
|
||||||
|
* the boot image, since at that time we do not have root.
|
||||||
|
* Check for dtbo status every boot time, and prompt user
|
||||||
|
* to reboot if dtbo wasn't patched and patched by Magisk Manager.
|
||||||
|
* */
|
||||||
|
MagiskManager mm = Utils.getMagiskManager(this);
|
||||||
|
mm.loadMagiskInfo();
|
||||||
|
if (Shell.rootAccess()) {
|
||||||
|
Utils.patchDTBO();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,13 +59,14 @@ public class Const {
|
|||||||
public static final int MAGISK_UPDATE_NOTIFICATION_ID = 4;
|
public static final int MAGISK_UPDATE_NOTIFICATION_ID = 4;
|
||||||
public static final int APK_UPDATE_NOTIFICATION_ID = 5;
|
public static final int APK_UPDATE_NOTIFICATION_ID = 5;
|
||||||
public static final int ONBOOT_NOTIFICATION_ID = 6;
|
public static final int ONBOOT_NOTIFICATION_ID = 6;
|
||||||
public static final String NOTIFICATION_CHANNEL = "magisk_update_notice";
|
public static final int DTBO_NOTIFICATION_ID = 7;
|
||||||
|
public static final String NOTIFICATION_CHANNEL = "magisk_notification";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Url {
|
public static class Url {
|
||||||
public static final String STABLE_URL = "https://raw.githubusercontent.com/topjohnwu/MagiskManager/update/stable.json";
|
public static final String STABLE_URL = "https://raw.githubusercontent.com/topjohnwu/MagiskManager/update/stable.json";
|
||||||
public static final String BETA_URL = "https://raw.githubusercontent.com/topjohnwu/MagiskManager/update/beta.json";
|
public static final String BETA_URL = "https://raw.githubusercontent.com/topjohnwu/MagiskManager/update/stable.json";
|
||||||
public static final String SNET_URL = "https://www.dropbox.com/s/jg2yhcrn3l9fckc/snet.apk?dl=1";
|
public static final String SNET_URL = "https://www.dropbox.com/s/vbq6y8pzfn4rq60/snet.apk?dl=1";
|
||||||
public static final String REPO_URL = "https://api.github.com/users/Magisk-Modules-Repo/repos?per_page=100&page=%d";
|
public static final String REPO_URL = "https://api.github.com/users/Magisk-Modules-Repo/repos?per_page=100&page=%d";
|
||||||
public static final String FILE_URL = "https://raw.githubusercontent.com/Magisk-Modules-Repo/%s/master/%s";
|
public static final String FILE_URL = "https://raw.githubusercontent.com/Magisk-Modules-Repo/%s/master/%s";
|
||||||
public static final String ZIP_URL = "https://github.com/Magisk-Modules-Repo/%s/archive/master.zip";
|
public static final String ZIP_URL = "https://github.com/Magisk-Modules-Repo/%s/archive/master.zip";
|
||||||
|
@ -78,6 +78,22 @@ public class Shell {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (rootAccess()) {
|
||||||
|
// Load utility shell scripts
|
||||||
|
try (InputStream in = mm.getAssets().open(Const.UTIL_FUNCTIONS)) {
|
||||||
|
mm.shell.loadInputStream(in);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Root shell initialization
|
||||||
|
mm.shell.run_raw(false,
|
||||||
|
"export PATH=" + Const.BUSYBOXPATH + ":$PATH",
|
||||||
|
"mount_partitions",
|
||||||
|
"find_boot_image",
|
||||||
|
"migrate_boot_backup"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return mm.shell;
|
return mm.shell;
|
||||||
|
@ -13,7 +13,6 @@ import android.support.v7.app.AlertDialog;
|
|||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.topjohnwu.magisk.FlashActivity;
|
import com.topjohnwu.magisk.FlashActivity;
|
||||||
import com.topjohnwu.magisk.MagiskFragment;
|
|
||||||
import com.topjohnwu.magisk.MagiskManager;
|
import com.topjohnwu.magisk.MagiskManager;
|
||||||
import com.topjohnwu.magisk.R;
|
import com.topjohnwu.magisk.R;
|
||||||
import com.topjohnwu.magisk.SplashActivity;
|
import com.topjohnwu.magisk.SplashActivity;
|
||||||
@ -21,6 +20,7 @@ import com.topjohnwu.magisk.asyncs.RestoreStockBoot;
|
|||||||
import com.topjohnwu.magisk.components.AlertDialogBuilder;
|
import com.topjohnwu.magisk.components.AlertDialogBuilder;
|
||||||
import com.topjohnwu.magisk.receivers.DownloadReceiver;
|
import com.topjohnwu.magisk.receivers.DownloadReceiver;
|
||||||
import com.topjohnwu.magisk.receivers.ManagerUpdate;
|
import com.topjohnwu.magisk.receivers.ManagerUpdate;
|
||||||
|
import com.topjohnwu.magisk.receivers.RebootReceiver;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
@ -31,14 +31,9 @@ import java.util.List;
|
|||||||
|
|
||||||
public class ShowUI {
|
public class ShowUI {
|
||||||
|
|
||||||
public static void showMagiskUpdateNotification() {
|
public static void magiskUpdateNotification() {
|
||||||
MagiskManager mm = MagiskManager.get();
|
MagiskManager mm = MagiskManager.get();
|
||||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(mm, Const.ID.NOTIFICATION_CHANNEL);
|
|
||||||
builder.setSmallIcon(R.drawable.ic_magisk)
|
|
||||||
.setContentTitle(mm.getString(R.string.magisk_update_title))
|
|
||||||
.setContentText(mm.getString(R.string.magisk_update_available, mm.remoteMagiskVersionString))
|
|
||||||
.setVibrate(new long[]{0, 100, 100, 100})
|
|
||||||
.setAutoCancel(true);
|
|
||||||
Intent intent = new Intent(mm, SplashActivity.class);
|
Intent intent = new Intent(mm, SplashActivity.class);
|
||||||
intent.putExtra(Const.Key.OPEN_SECTION, "magisk");
|
intent.putExtra(Const.Key.OPEN_SECTION, "magisk");
|
||||||
TaskStackBuilder stackBuilder = TaskStackBuilder.create(mm);
|
TaskStackBuilder stackBuilder = TaskStackBuilder.create(mm);
|
||||||
@ -46,35 +41,65 @@ public class ShowUI {
|
|||||||
stackBuilder.addNextIntent(intent);
|
stackBuilder.addNextIntent(intent);
|
||||||
PendingIntent pendingIntent = stackBuilder.getPendingIntent(Const.ID.MAGISK_UPDATE_NOTIFICATION_ID,
|
PendingIntent pendingIntent = stackBuilder.getPendingIntent(Const.ID.MAGISK_UPDATE_NOTIFICATION_ID,
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT);
|
PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
builder.setContentIntent(pendingIntent);
|
|
||||||
|
NotificationCompat.Builder builder = new NotificationCompat.Builder(mm, Const.ID.NOTIFICATION_CHANNEL);
|
||||||
|
builder.setSmallIcon(R.drawable.ic_magisk)
|
||||||
|
.setContentTitle(mm.getString(R.string.magisk_update_title))
|
||||||
|
.setContentText(mm.getString(R.string.magisk_update_available, mm.remoteMagiskVersionString))
|
||||||
|
.setVibrate(new long[]{0, 100, 100, 100})
|
||||||
|
.setAutoCancel(true)
|
||||||
|
.setContentIntent(pendingIntent);
|
||||||
|
|
||||||
NotificationManager notificationManager =
|
NotificationManager notificationManager =
|
||||||
(NotificationManager) mm.getSystemService(Context.NOTIFICATION_SERVICE);
|
(NotificationManager) mm.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
notificationManager.notify(Const.ID.MAGISK_UPDATE_NOTIFICATION_ID, builder.build());
|
notificationManager.notify(Const.ID.MAGISK_UPDATE_NOTIFICATION_ID, builder.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void showManagerUpdateNotification() {
|
public static void managerUpdateNotification() {
|
||||||
MagiskManager mm = MagiskManager.get();
|
MagiskManager mm = MagiskManager.get();
|
||||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(mm, Const.ID.NOTIFICATION_CHANNEL);
|
|
||||||
builder.setSmallIcon(R.drawable.ic_magisk)
|
|
||||||
.setContentTitle(mm.getString(R.string.manager_update_title))
|
|
||||||
.setContentText(mm.getString(R.string.manager_download_install))
|
|
||||||
.setVibrate(new long[]{0, 100, 100, 100})
|
|
||||||
.setAutoCancel(true);
|
|
||||||
Intent intent = new Intent(mm, ManagerUpdate.class);
|
Intent intent = new Intent(mm, ManagerUpdate.class);
|
||||||
intent.putExtra(Const.Key.INTENT_SET_LINK, mm.managerLink);
|
intent.putExtra(Const.Key.INTENT_SET_LINK, mm.managerLink);
|
||||||
intent.putExtra(Const.Key.INTENT_SET_VERSION, mm.remoteManagerVersionString);
|
intent.putExtra(Const.Key.INTENT_SET_VERSION, mm.remoteManagerVersionString);
|
||||||
PendingIntent pendingIntent = PendingIntent.getBroadcast(mm,
|
PendingIntent pendingIntent = PendingIntent.getBroadcast(mm,
|
||||||
Const.ID.APK_UPDATE_NOTIFICATION_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
Const.ID.APK_UPDATE_NOTIFICATION_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
builder.setContentIntent(pendingIntent);
|
|
||||||
|
NotificationCompat.Builder builder = new NotificationCompat.Builder(mm, Const.ID.NOTIFICATION_CHANNEL);
|
||||||
|
builder.setSmallIcon(R.drawable.ic_magisk)
|
||||||
|
.setContentTitle(mm.getString(R.string.manager_update_title))
|
||||||
|
.setContentText(mm.getString(R.string.manager_download_install))
|
||||||
|
.setVibrate(new long[]{0, 100, 100, 100})
|
||||||
|
.setAutoCancel(true)
|
||||||
|
.setContentIntent(pendingIntent);
|
||||||
|
|
||||||
NotificationManager notificationManager =
|
NotificationManager notificationManager =
|
||||||
(NotificationManager) mm.getSystemService(Context.NOTIFICATION_SERVICE);
|
(NotificationManager) mm.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
notificationManager.notify(Const.ID.APK_UPDATE_NOTIFICATION_ID, builder.build());
|
notificationManager.notify(Const.ID.APK_UPDATE_NOTIFICATION_ID, builder.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void showMagiskInstallDialog(MagiskFragment fragment, boolean enc, boolean verity) {
|
public static void dtboPatchedNotification() {
|
||||||
MagiskManager mm = Utils.getMagiskManager(fragment.getContext());
|
MagiskManager mm = MagiskManager.get();
|
||||||
|
|
||||||
|
Intent intent = new Intent(mm, RebootReceiver.class);
|
||||||
|
PendingIntent pendingIntent = PendingIntent.getBroadcast(mm,
|
||||||
|
Const.ID.DTBO_NOTIFICATION_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
|
|
||||||
|
NotificationCompat.Builder builder = new NotificationCompat.Builder(mm, Const.ID.NOTIFICATION_CHANNEL);
|
||||||
|
builder.setSmallIcon(R.drawable.ic_magisk)
|
||||||
|
.setContentTitle(mm.getString(R.string.dtbo_patched_title))
|
||||||
|
.setContentText(mm.getString(R.string.dtbo_patched_reboot))
|
||||||
|
.setVibrate(new long[]{0, 100, 100, 100})
|
||||||
|
.addAction(R.drawable.ic_refresh, mm.getString(R.string.reboot), pendingIntent);
|
||||||
|
|
||||||
|
NotificationManager notificationManager =
|
||||||
|
(NotificationManager) mm.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
|
notificationManager.notify(Const.ID.DTBO_NOTIFICATION_ID, builder.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void magiskInstallDialog(Activity activity, boolean enc, boolean verity) {
|
||||||
|
MagiskManager mm = Utils.getMagiskManager(activity);
|
||||||
String filename = Utils.getLegalFilename("Magisk-v" + mm.remoteMagiskVersionString + ".zip");
|
String filename = Utils.getLegalFilename("Magisk-v" + mm.remoteMagiskVersionString + ".zip");
|
||||||
new AlertDialogBuilder(fragment.getActivity())
|
new AlertDialogBuilder(activity)
|
||||||
.setTitle(mm.getString(R.string.repo_install_title, mm.getString(R.string.magisk)))
|
.setTitle(mm.getString(R.string.repo_install_title, mm.getString(R.string.magisk)))
|
||||||
.setMessage(mm.getString(R.string.repo_install_msg, filename))
|
.setMessage(mm.getString(R.string.repo_install_msg, filename))
|
||||||
.setCancelable(true)
|
.setCancelable(true)
|
||||||
@ -90,7 +115,7 @@ public class ShowUI {
|
|||||||
options.add(mm.getString(R.string.install_second_slot));
|
options.add(mm.getString(R.string.install_second_slot));
|
||||||
}
|
}
|
||||||
char[] slot = Utils.isValidShellResponse(res) ? res.get(0).toCharArray() : null;
|
char[] slot = Utils.isValidShellResponse(res) ? res.get(0).toCharArray() : null;
|
||||||
new AlertDialog.Builder(fragment.getActivity())
|
new AlertDialog.Builder(activity)
|
||||||
.setTitle(R.string.select_method)
|
.setTitle(R.string.select_method)
|
||||||
.setItems(
|
.setItems(
|
||||||
options.toArray(new String [0]),
|
options.toArray(new String [0]),
|
||||||
@ -106,12 +131,13 @@ public class ShowUI {
|
|||||||
MagiskManager.toast(R.string.boot_file_patch_msg, Toast.LENGTH_LONG);
|
MagiskManager.toast(R.string.boot_file_patch_msg, Toast.LENGTH_LONG);
|
||||||
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
|
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
|
||||||
intent.setType("*/*");
|
intent.setType("*/*");
|
||||||
fragment.startActivityForResult(intent, Const.ID.SELECT_BOOT,
|
((com.topjohnwu.magisk.components.Activity) activity)
|
||||||
|
.startActivityForResult(intent, Const.ID.SELECT_BOOT,
|
||||||
(requestCode, resultCode, data) -> {
|
(requestCode, resultCode, data) -> {
|
||||||
if (requestCode == Const.ID.SELECT_BOOT
|
if (requestCode == Const.ID.SELECT_BOOT
|
||||||
&& resultCode == Activity.RESULT_OK && data != null) {
|
&& resultCode == Activity.RESULT_OK && data != null) {
|
||||||
Utils.dlAndReceive(
|
Utils.dlAndReceive(
|
||||||
fragment.getActivity(),
|
activity,
|
||||||
new DownloadReceiver() {
|
new DownloadReceiver() {
|
||||||
@Override
|
@Override
|
||||||
public void onDownloadDone(Uri uri) {
|
public void onDownloadDone(Uri uri) {
|
||||||
@ -135,12 +161,12 @@ public class ShowUI {
|
|||||||
receiver = new DownloadReceiver() {
|
receiver = new DownloadReceiver() {
|
||||||
@Override
|
@Override
|
||||||
public void onDownloadDone(Uri uri) {
|
public void onDownloadDone(Uri uri) {
|
||||||
Utils.showUriSnack(fragment.getActivity(), uri);
|
Utils.showUriSnack(activity, uri);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
boot = fragment.getSelectedBootImage();
|
boot = mm.bootBlock;
|
||||||
if (boot == null)
|
if (boot == null)
|
||||||
return;
|
return;
|
||||||
receiver = new DownloadReceiver() {
|
receiver = new DownloadReceiver() {
|
||||||
@ -148,12 +174,11 @@ public class ShowUI {
|
|||||||
public void onDownloadDone(Uri uri) {
|
public void onDownloadDone(Uri uri) {
|
||||||
Intent intent = new Intent(mm, FlashActivity.class);
|
Intent intent = new Intent(mm, FlashActivity.class);
|
||||||
intent.setData(uri)
|
intent.setData(uri)
|
||||||
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
|
||||||
.putExtra(Const.Key.FLASH_SET_BOOT, boot)
|
.putExtra(Const.Key.FLASH_SET_BOOT, boot)
|
||||||
.putExtra(Const.Key.FLASH_SET_ENC, enc)
|
.putExtra(Const.Key.FLASH_SET_ENC, enc)
|
||||||
.putExtra(Const.Key.FLASH_SET_VERITY, verity)
|
.putExtra(Const.Key.FLASH_SET_VERITY, verity)
|
||||||
.putExtra(Const.Key.FLASH_ACTION, Const.Value.FLASH_MAGISK);
|
.putExtra(Const.Key.FLASH_ACTION, Const.Value.FLASH_MAGISK);
|
||||||
mm.startActivity(intent);
|
activity.startActivity(intent);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
@ -164,7 +189,6 @@ public class ShowUI {
|
|||||||
else slot[1] = 'a';
|
else slot[1] = 'a';
|
||||||
// Then find the boot image again
|
// Then find the boot image again
|
||||||
List<String> ret = Shell.su(
|
List<String> ret = Shell.su(
|
||||||
"BOOTIMAGE=",
|
|
||||||
"SLOT=" + String.valueOf(slot),
|
"SLOT=" + String.valueOf(slot),
|
||||||
"find_boot_image",
|
"find_boot_image",
|
||||||
"echo \"$BOOTIMAGE\""
|
"echo \"$BOOTIMAGE\""
|
||||||
@ -178,18 +202,17 @@ public class ShowUI {
|
|||||||
public void onDownloadDone(Uri uri) {
|
public void onDownloadDone(Uri uri) {
|
||||||
Intent intent = new Intent(mm, FlashActivity.class);
|
Intent intent = new Intent(mm, FlashActivity.class);
|
||||||
intent.setData(uri)
|
intent.setData(uri)
|
||||||
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
|
||||||
.putExtra(Const.Key.FLASH_SET_BOOT, boot)
|
.putExtra(Const.Key.FLASH_SET_BOOT, boot)
|
||||||
.putExtra(Const.Key.FLASH_SET_ENC, enc)
|
.putExtra(Const.Key.FLASH_SET_ENC, enc)
|
||||||
.putExtra(Const.Key.FLASH_SET_VERITY, verity)
|
.putExtra(Const.Key.FLASH_SET_VERITY, verity)
|
||||||
.putExtra(Const.Key.FLASH_ACTION, Const.Value.FLASH_MAGISK);
|
.putExtra(Const.Key.FLASH_ACTION, Const.Value.FLASH_MAGISK);
|
||||||
mm.startActivity(intent);
|
activity.startActivity(intent);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
Utils.dlAndReceive(
|
Utils.dlAndReceive(
|
||||||
fragment.getActivity(),
|
activity,
|
||||||
receiver,
|
receiver,
|
||||||
mm.magiskLink,
|
mm.magiskLink,
|
||||||
filename
|
filename
|
||||||
@ -208,7 +231,7 @@ public class ShowUI {
|
|||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void showManagerInstallDialog(Activity activity) {
|
public static void managerInstallDialog(Activity activity) {
|
||||||
MagiskManager mm = Utils.getMagiskManager(activity);
|
MagiskManager mm = Utils.getMagiskManager(activity);
|
||||||
new AlertDialogBuilder(activity)
|
new AlertDialogBuilder(activity)
|
||||||
.setTitle(mm.getString(R.string.repo_install_title, mm.getString(R.string.app_name)))
|
.setTitle(mm.getString(R.string.repo_install_title, mm.getString(R.string.app_name)))
|
||||||
@ -228,9 +251,9 @@ public class ShowUI {
|
|||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void showUninstallDialog(MagiskFragment fragment) {
|
public static void uninstallDialog(Activity activity) {
|
||||||
MagiskManager mm = Utils.getMagiskManager(fragment.getActivity());
|
MagiskManager mm = Utils.getMagiskManager(activity);
|
||||||
new AlertDialogBuilder(fragment.getActivity())
|
new AlertDialogBuilder(activity)
|
||||||
.setTitle(R.string.uninstall_magisk_title)
|
.setTitle(R.string.uninstall_magisk_title)
|
||||||
.setMessage(R.string.uninstall_magisk_msg)
|
.setMessage(R.string.uninstall_magisk_msg)
|
||||||
.setPositiveButton(R.string.complete_uninstall, (d, i) -> {
|
.setPositiveButton(R.string.complete_uninstall, (d, i) -> {
|
||||||
@ -267,9 +290,7 @@ public class ShowUI {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.setNeutralButton(R.string.restore_stock_boot, (d, i) -> {
|
.setNeutralButton(R.string.restore_stock_boot, (d, i) -> {
|
||||||
String boot = fragment.getSelectedBootImage();
|
new RestoreStockBoot().exec();
|
||||||
if (boot == null) return;
|
|
||||||
new RestoreStockBoot(boot).exec();
|
|
||||||
})
|
})
|
||||||
.setNegativeButton(R.string.no_thanks, null)
|
.setNegativeButton(R.string.no_thanks, null)
|
||||||
.show();
|
.show();
|
||||||
|
@ -234,4 +234,13 @@ public class Utils {
|
|||||||
}
|
}
|
||||||
out.flush();
|
out.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void patchDTBO() {
|
||||||
|
if (MagiskManager.get().magiskVersionCode >= 1446) {
|
||||||
|
List<String> ret = Shell.su("patch_dtbo_image && echo true || echo false");
|
||||||
|
if (Utils.isValidShellResponse(ret) && Boolean.parseBoolean(ret.get(ret.size() - 1))) {
|
||||||
|
ShowUI.dtboPatchedNotification();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -224,61 +224,6 @@
|
|||||||
|
|
||||||
</android.support.v7.widget.CardView>
|
</android.support.v7.widget.CardView>
|
||||||
|
|
||||||
<android.support.v7.widget.CardView
|
|
||||||
android:id="@+id/bootimage_card"
|
|
||||||
style="?attr/cardStyle"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:layout_marginBottom="4dp"
|
|
||||||
android:layout_marginEnd="5dp"
|
|
||||||
android:layout_marginStart="5dp"
|
|
||||||
android:layout_marginTop="4dp"
|
|
||||||
app:cardCornerRadius="@dimen/card_corner_radius"
|
|
||||||
app:cardElevation="@dimen/card_elevation" >
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_marginBottom="15dp"
|
|
||||||
android:layout_marginTop="15dp"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:gravity="center"
|
|
||||||
android:paddingBottom="10dp"
|
|
||||||
android:text="@string/boot_image_title"
|
|
||||||
android:textStyle="bold" />
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_marginEnd="25dp"
|
|
||||||
android:layout_marginStart="25dp"
|
|
||||||
android:minHeight="35dp"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
|
|
||||||
<Spinner
|
|
||||||
android:id="@+id/block_spinner"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_weight="1" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/detect_bootimage"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/detect_button"
|
|
||||||
android:visibility="gone" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</android.support.v7.widget.CardView>
|
|
||||||
|
|
||||||
<android.support.v7.widget.CardView
|
<android.support.v7.widget.CardView
|
||||||
android:id="@+id/install_option_card"
|
android:id="@+id/install_option_card"
|
||||||
style="?attr/cardStyle"
|
style="?attr/cardStyle"
|
||||||
|
@ -106,6 +106,8 @@
|
|||||||
<string name="manual_boot_image">Please manually select a boot image!</string>
|
<string name="manual_boot_image">Please manually select a boot image!</string>
|
||||||
<string name="manager_update_title">New Magisk Manager Update Available!</string>
|
<string name="manager_update_title">New Magisk Manager Update Available!</string>
|
||||||
<string name="manager_download_install">Press to download and install</string>
|
<string name="manager_download_install">Press to download and install</string>
|
||||||
|
<string name="dtbo_patched_title">DTBO was patched!</string>
|
||||||
|
<string name="dtbo_patched_reboot">Magisk Manager has patched dtbo.img, please reboot</string>
|
||||||
<string name="magisk_updates">Magisk Updates</string>
|
<string name="magisk_updates">Magisk Updates</string>
|
||||||
<string name="flashing">Flashing</string>
|
<string name="flashing">Flashing</string>
|
||||||
<string name="hide_manager_toast">Hiding Magisk Manager…</string>
|
<string name="hide_manager_toast">Hiding Magisk Manager…</string>
|
||||||
|
Loading…
Reference in New Issue
Block a user