Fully support dtbo.img patching

This commit is contained in:
topjohnwu 2017-11-15 04:39:05 +08:00
parent 4ac83cfded
commit 826543a291
18 changed files with 157 additions and 207 deletions

View File

@ -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

View File

@ -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() {

View File

@ -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

View File

@ -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

View File

@ -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();

View File

@ -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;

View File

@ -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

View File

@ -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);
}
} }

View File

@ -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);
}
} }

View File

@ -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);
}
} }
} }

View File

@ -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");
}
}

View File

@ -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();
}
} }
} }

View File

@ -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";

View File

@ -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;

View File

@ -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();

View File

@ -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();
}
}
}
} }

View File

@ -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"

View File

@ -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>