Search in sources :

Example 6 with MagiskManager

use of com.topjohnwu.magisk.MagiskManager in project MagiskManager by topjohnwu.

the class OnBootIntentService method onHandleIntent.

@Override
protected void onHandleIntent(Intent intent) {
    /* 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();
    mm.getDefaultInstallFlags();
    if (Shell.rootAccess()) {
        Utils.patchDTBO();
    }
}
Also used : MagiskManager(com.topjohnwu.magisk.MagiskManager)

Example 7 with MagiskManager

use of com.topjohnwu.magisk.MagiskManager in project MagiskManager by topjohnwu.

the class PackageReceiver method onReceive.

@Override
public void onReceive(Context context, Intent intent) {
    MagiskManager mm = Utils.getMagiskManager(context);
    String pkg = intent.getData().getEncodedSchemeSpecificPart();
    switch(intent.getAction()) {
        case Intent.ACTION_PACKAGE_REPLACED:
            // This will only work pre-O
            if (mm.prefs.getBoolean(Const.Key.SU_REAUTH, false)) {
                mm.suDB.deletePolicy(pkg);
            }
            break;
        case Intent.ACTION_PACKAGE_FULLY_REMOVED:
            mm.suDB.deletePolicy(pkg);
            Shell.Async.su("magiskhide --rm " + pkg);
            break;
    }
}
Also used : MagiskManager(com.topjohnwu.magisk.MagiskManager)

Example 8 with MagiskManager

use of com.topjohnwu.magisk.MagiskManager in project MagiskManager by topjohnwu.

the class Utils method loadPrefs.

public static void loadPrefs() {
    SuFile config = new SuFile(fmt("/data/user/%d/%s", Const.USER_ID, Const.MANAGER_CONFIGS), true);
    if (config.exists()) {
        MagiskManager mm = MagiskManager.get();
        SharedPreferences.Editor editor = mm.prefs.edit();
        try {
            SuFileInputStream is = new SuFileInputStream(config);
            XmlPullParser parser = Xml.newPullParser();
            parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
            parser.setInput(is, "UTF-8");
            parser.nextTag();
            parser.require(XmlPullParser.START_TAG, null, "map");
            while (parser.next() != XmlPullParser.END_TAG) {
                if (parser.getEventType() != XmlPullParser.START_TAG)
                    continue;
                String key = parser.getAttributeValue(null, "name");
                String value = parser.getAttributeValue(null, "value");
                switch(parser.getName()) {
                    case "string":
                        parser.require(XmlPullParser.START_TAG, null, "string");
                        editor.putString(key, parser.nextText());
                        parser.require(XmlPullParser.END_TAG, null, "string");
                        break;
                    case "boolean":
                        parser.require(XmlPullParser.START_TAG, null, "boolean");
                        editor.putBoolean(key, Boolean.parseBoolean(value));
                        parser.nextTag();
                        parser.require(XmlPullParser.END_TAG, null, "boolean");
                        break;
                    case "int":
                        parser.require(XmlPullParser.START_TAG, null, "int");
                        editor.putInt(key, Integer.parseInt(value));
                        parser.nextTag();
                        parser.require(XmlPullParser.END_TAG, null, "int");
                        break;
                    case "long":
                        parser.require(XmlPullParser.START_TAG, null, "long");
                        editor.putLong(key, Long.parseLong(value));
                        parser.nextTag();
                        parser.require(XmlPullParser.END_TAG, null, "long");
                        break;
                    case "float":
                        parser.require(XmlPullParser.START_TAG, null, "int");
                        editor.putFloat(key, Float.parseFloat(value));
                        parser.nextTag();
                        parser.require(XmlPullParser.END_TAG, null, "int");
                        break;
                    default:
                        parser.next();
                }
            }
        } catch (IOException | XmlPullParserException e) {
            e.printStackTrace();
        }
        editor.remove(Const.Key.ETAG_KEY);
        editor.apply();
        mm.loadConfig();
        config.delete();
    }
}
Also used : SuFileInputStream(com.topjohnwu.superuser.io.SuFileInputStream) SharedPreferences(android.content.SharedPreferences) MagiskManager(com.topjohnwu.magisk.MagiskManager) XmlPullParser(org.xmlpull.v1.XmlPullParser) SuFile(com.topjohnwu.superuser.io.SuFile) XmlPullParserException(org.xmlpull.v1.XmlPullParserException) IOException(java.io.IOException)

Example 9 with MagiskManager

use of com.topjohnwu.magisk.MagiskManager in project MagiskManager by topjohnwu.

the class ShowUI method magiskUpdateNotification.

public static void magiskUpdateNotification() {
    MagiskManager mm = MagiskManager.get();
    Intent intent = new Intent(mm, SplashActivity.class);
    intent.putExtra(Const.Key.OPEN_SECTION, "magisk");
    TaskStackBuilder stackBuilder = TaskStackBuilder.create(mm);
    stackBuilder.addParentStack(SplashActivity.class);
    stackBuilder.addNextIntent(intent);
    PendingIntent pendingIntent = stackBuilder.getPendingIntent(Const.ID.MAGISK_UPDATE_NOTIFICATION_ID, 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.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) mm.getSystemService(Context.NOTIFICATION_SERVICE);
    notificationManager.notify(Const.ID.MAGISK_UPDATE_NOTIFICATION_ID, builder.build());
}
Also used : NotificationManager(android.app.NotificationManager) MagiskManager(com.topjohnwu.magisk.MagiskManager) AlertDialogBuilder(com.topjohnwu.magisk.components.AlertDialogBuilder) TaskStackBuilder(android.support.v4.app.TaskStackBuilder) NotificationCompat(android.support.v4.app.NotificationCompat) Intent(android.content.Intent) PendingIntent(android.app.PendingIntent) PendingIntent(android.app.PendingIntent) TaskStackBuilder(android.support.v4.app.TaskStackBuilder)

Example 10 with MagiskManager

use of com.topjohnwu.magisk.MagiskManager in project MagiskManager by topjohnwu.

the class InstallMagisk method doInBackground.

@Override
protected Boolean doInBackground(Void... voids) {
    MagiskManager mm = MagiskManager.get();
    install = new File((Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ? mm.createDeviceProtectedStorageContext() : mm).getFilesDir().getParent(), "install");
    Shell.Sync.sh("rm -rf " + install);
    List<String> abis = Arrays.asList(Build.SUPPORTED_ABIS);
    String arch;
    if (abis.contains("x86_64"))
        arch = "x64";
    else if (abis.contains("arm64-v8a"))
        arch = "arm64";
    else if (abis.contains("x86"))
        arch = "x86";
    else
        arch = "arm";
    console.add("- Device platform: " + arch);
    try {
        // Unzip files
        console.add("- Extracting files");
        try (InputStream in = mm.getContentResolver().openInputStream(mZip)) {
            if (in == null)
                throw new FileNotFoundException();
            BufferedInputStream buf = new BufferedInputStream(in);
            buf.mark(Integer.MAX_VALUE);
            ZipUtils.unzip(buf, install, arch + "/", true);
            buf.reset();
            ZipUtils.unzip(buf, install, "common/", true);
            buf.reset();
            ZipUtils.unzip(buf, install, "chromeos/", false);
            buf.reset();
            ZipUtils.unzip(buf, install, "META-INF/com/google/android/update-binary", true);
            buf.close();
        } catch (FileNotFoundException e) {
            console.add("! Invalid Uri");
            throw e;
        } catch (Exception e) {
            console.add("! Cannot unzip zip");
            throw e;
        }
        Shell.Sync.sh("chmod 755 " + install + "/*");
        File boot = new File(install, "boot.img");
        boolean highCompression = false;
        switch(mode) {
            case PATCH_MODE:
                // Copy boot image to local
                try (InputStream in = mm.getContentResolver().openInputStream(mBootImg);
                    OutputStream out = new FileOutputStream(boot)) {
                    InputStream source;
                    if (in == null)
                        throw new FileNotFoundException();
                    if (Utils.getNameFromUri(mm, mBootImg).endsWith(".tar")) {
                        // Extract boot.img from tar
                        TarInputStream tar = new TarInputStream(new BufferedInputStream(in));
                        org.kamranzafar.jtar.TarEntry entry;
                        while ((entry = tar.getNextEntry()) != null) {
                            if (entry.getName().equals("boot.img"))
                                break;
                        }
                        source = tar;
                    } else {
                        // Direct copy raw image
                        source = new BufferedInputStream(in);
                    }
                    ShellUtils.pump(source, out);
                } catch (FileNotFoundException e) {
                    console.add("! Invalid Uri");
                    throw e;
                } catch (IOException e) {
                    console.add("! Copy failed");
                    throw e;
                }
                break;
            case DIRECT_MODE:
                console.add("- Patch boot/ramdisk image: " + mBootLocation);
                if (mm.remoteMagiskVersionCode >= 1463) {
                    highCompression = Integer.parseInt(Utils.cmd(Utils.fmt("%s/magiskboot --parse %s; echo $?", install, mBootLocation))) == 2;
                    if (highCompression)
                        console.add("! Insufficient boot partition size detected");
                }
                if (boot.createNewFile()) {
                    Shell.Sync.su("cat " + mBootLocation + " > " + boot);
                } else {
                    console.add("! Dump boot image failed");
                    return false;
                }
                break;
            default:
                return false;
        }
        boolean isSigned;
        try (InputStream in = new FileInputStream(boot)) {
            isSigned = SignBoot.verifySignature(in, null);
            if (isSigned) {
                console.add("- Boot image is signed with AVB 1.0");
            }
        } catch (Exception e) {
            console.add("! Unable to check signature");
            throw e;
        }
        // Patch boot image
        Shell.Sync.sh(console, logs, "cd " + install, Utils.fmt("KEEPFORCEENCRYPT=%b KEEPVERITY=%b HIGHCOMP=%b " + "sh update-binary indep boot_patch.sh %s || echo 'Failed!'", mm.keepEnc, mm.keepVerity, highCompression, boot));
        if (TextUtils.equals(console.get(console.size() - 1), "Failed!"))
            return false;
        Shell.Sync.sh("mv -f new-boot.img ../", "mv bin/busybox busybox", "rm -rf bin *.img update-binary", "cd /");
        SuFile patched_boot = new SuFile(install.getParent(), "new-boot.img");
        if (isSigned) {
            console.add("- Signing boot image with test keys");
            File signed = new File(install.getParent(), "signed.img");
            try (InputStream in = new SuFileInputStream(patched_boot);
                OutputStream out = new BufferedOutputStream(new FileOutputStream(signed))) {
                SignBoot.doSignature("/boot", in, out, null, null);
            }
            Shell.Sync.sh("mv -f " + signed + " " + patched_boot);
        }
        switch(mode) {
            case PATCH_MODE:
                File dest = new File(Const.EXTERNAL_PATH, "patched_boot" + mm.bootFormat);
                dest.getParentFile().mkdirs();
                OutputStream out;
                switch(mm.bootFormat) {
                    case ".img.tar":
                        out = new TarOutputStream(new BufferedOutputStream(new FileOutputStream(dest)));
                        ((TarOutputStream) out).putNextEntry(new TarEntry(patched_boot, "boot.img"));
                        break;
                    default:
                    case ".img":
                        out = new BufferedOutputStream(new FileOutputStream(dest));
                        break;
                }
                try (InputStream in = new SuFileInputStream(patched_boot)) {
                    ShellUtils.pump(in, out);
                    out.close();
                }
                console.add("");
                console.add("*********************************");
                console.add(" Patched Boot Image is placed in ");
                console.add(" " + dest + " ");
                console.add("*********************************");
                break;
            case DIRECT_MODE:
                String binPath = mm.remoteMagiskVersionCode >= 1464 ? "/data/adb/magisk" : "/data/magisk";
                Shell.Sync.su(console, logs, Utils.fmt("rm -rf %s/*; mkdir -p %s; chmod 700 /data/adb", binPath, binPath), Utils.fmt("cp -af %s/* %s; rm -rf %s", install, binPath, install), Utils.fmt("flash_boot_image %s %s", patched_boot, mBootLocation), mm.remoteMagiskVersionCode >= 1464 ? "[ -L /data/magisk.img ] || cp /data/magisk.img /data/adb/magisk.img" : "", mm.keepVerity ? "" : "patch_dtbo_image");
                break;
            default:
                return false;
        }
        patched_boot.delete();
        console.add("- All done!");
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
    return true;
}
Also used : TarOutputStream(org.kamranzafar.jtar.TarOutputStream) MagiskManager(com.topjohnwu.magisk.MagiskManager) BufferedInputStream(java.io.BufferedInputStream) FileInputStream(java.io.FileInputStream) TarInputStream(org.kamranzafar.jtar.TarInputStream) SuFileInputStream(com.topjohnwu.superuser.io.SuFileInputStream) InputStream(java.io.InputStream) BufferedOutputStream(java.io.BufferedOutputStream) OutputStream(java.io.OutputStream) FileOutputStream(java.io.FileOutputStream) TarOutputStream(org.kamranzafar.jtar.TarOutputStream) FileNotFoundException(java.io.FileNotFoundException) SuFile(com.topjohnwu.superuser.io.SuFile) TarEntry(com.topjohnwu.magisk.container.TarEntry) IOException(java.io.IOException) IOException(java.io.IOException) FileNotFoundException(java.io.FileNotFoundException) FileInputStream(java.io.FileInputStream) SuFileInputStream(com.topjohnwu.superuser.io.SuFileInputStream) SuFileInputStream(com.topjohnwu.superuser.io.SuFileInputStream) BufferedInputStream(java.io.BufferedInputStream) TarInputStream(org.kamranzafar.jtar.TarInputStream) FileOutputStream(java.io.FileOutputStream) SuFile(com.topjohnwu.superuser.io.SuFile) File(java.io.File) BufferedOutputStream(java.io.BufferedOutputStream)

Aggregations

MagiskManager (com.topjohnwu.magisk.MagiskManager)21 IOException (java.io.IOException)7 PendingIntent (android.app.PendingIntent)6 Intent (android.content.Intent)6 AlertDialogBuilder (com.topjohnwu.magisk.components.AlertDialogBuilder)6 InputStream (java.io.InputStream)6 NotificationManager (android.app.NotificationManager)5 NotificationCompat (android.support.v4.app.NotificationCompat)5 TaskStackBuilder (android.support.v4.app.TaskStackBuilder)5 SuFile (com.topjohnwu.superuser.io.SuFile)4 Activity (android.app.Activity)3 Shell (com.topjohnwu.superuser.Shell)3 ShellUtils (com.topjohnwu.superuser.ShellUtils)3 BufferedInputStream (java.io.BufferedInputStream)3 BufferedOutputStream (java.io.BufferedOutputStream)3 ByteArrayOutputStream (java.io.ByteArrayOutputStream)3 File (java.io.File)3 FileOutputStream (java.io.FileOutputStream)3 OutputStream (java.io.OutputStream)3 Manifest (android.Manifest)2