Java tutorial
/* * Copyright (C) Felipe de Leon <fglfgl27@gmail.com> * * This file is part of iSu. * * iSu is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * iSu is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with iSu. If not, see <http://www.gnu.org/licenses/>. * */ package com.bhb27.isu; import android.app.Activity; import android.content.ActivityNotFoundException; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.content.res.AssetManager; import android.graphics.Paint; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.support.v4.content.ContextCompat; import android.util.Log; import android.view.animation.AlphaAnimation; import android.view.animation.Animation; import android.view.View; import android.widget.Button; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.Switch; import android.widget.TextView; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.io.IOException; import java.io.OutputStream; import com.bhb27.isu.AboutActivity; import com.bhb27.isu.PerAppActivity; import com.bhb27.isu.tools.Constants; import com.bhb27.isu.tools.Tools; public class Main extends Activity { private TextView SuSwitchSummary, SuStatus, kernel_check, Selinux_State, su_version, su_version_summary, SelinuxStatus, download_folder_link, per_app_summary, SuSelinuxSwitchSummary; private Button about, per_app; private Switch suSwitch, SelinuxSwitch, iSuNotification, SuSelinuxSwitch; private String bin_su = Constants.bin_su; private String xbin_su = Constants.xbin_su; private String bin_isu = Constants.bin_isu; private String xbin_isu = Constants.xbin_isu; private String bin_temp_su = Constants.bin_temp_su; private ImageView ic_launcher; private String TAG = Constants.TAG; private final String sepolicy = Constants.sepolicy; private boolean upMain = false; private String suVersion; private boolean isCMSU; private Context MainContext = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); MainContext = this; LinearLayout layout = (LinearLayout) findViewById(R.id.MainLayout); AlphaAnimation animation = new AlphaAnimation(0.0f, 1.0f); animation.setFillAfter(true); animation.setDuration(750); layout.startAnimation(animation); suVersion = Tools.SuVersion(MainContext); isCMSU = SuVersionBool(suVersion); Runnable runSepolicy = new Runnable() { public void run() { Sepolicy(); // Only run boot service if app was used and is CM SU if (isCMSU && !Tools.getBoolean("run_boot", false, MainContext)) Tools.saveBoolean("run_boot", true, MainContext); } }; new Thread(runSepolicy).start(); suSwitch = (Switch) findViewById(R.id.suSwitch); SuSwitchSummary = (TextView) findViewById(R.id.SuSwitchSummary); SuStatus = (TextView) findViewById(R.id.SuStatus); su_version = (TextView) findViewById(R.id.su_version); su_version_summary = (TextView) findViewById(R.id.su_version_summary); su_version_summary.setText(suVersion); SelinuxSwitch = (Switch) findViewById(R.id.SelinuxSwitch); SelinuxStatus = (TextView) findViewById(R.id.SelinuxStatus); Selinux_State = (TextView) findViewById(R.id.Selinux_State); Selinux_State.setText(Tools.getSELinuxStatus()); iSuNotification = (Switch) findViewById(R.id.iSuNotification); SuSelinuxSwitch = (Switch) findViewById(R.id.SuSelinuxSwitch); SuSelinuxSwitchSummary = (TextView) findViewById(R.id.SuSelinuxSwitchSummary); per_app = (Button) findViewById(R.id.buttonPer_app); per_app_summary = (TextView) findViewById(R.id.per_app); download_folder_link = (TextView) findViewById(R.id.download_folder_link); kernel_check = (TextView) findViewById(R.id.kernel_check); // about button about = (Button) findViewById(R.id.buttonAbout); about.setOnClickListener(new View.OnClickListener() { Intent myIntent = new Intent(getApplicationContext(), AboutActivity.class); @Override public void onClick(View v) { startActivity(myIntent); } }); ic_launcher = (ImageView) findViewById(R.id.ic_launcher); ic_launcher.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Tools.DoAToast(getString(R.string.isu_by), MainContext); } }); //reboot support check if (RebootSupport()) { kernel_check.setText(getString(R.string.isu_reboot)); download_folder_link.setVisibility(View.GONE); } else if (Tools.KernelSupport()) { kernel_check.setText(getString(R.string.isu_kernel_good)); download_folder_link.setVisibility(View.GONE); } else { kernel_check.setTextColor(getColorWrapper(MainContext, R.color.colorAccent)); kernel_check.setText(getString(R.string.isu_kernel_bad)); download_folder_link.setText(getString(R.string.download_folder_link)); download_folder_link.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.androidfilehost.com/?w=files&flid=120360"))); } catch (ActivityNotFoundException ex) { Tools.DoAToast(getString(R.string.no_browser), MainContext); } } }); } UpdateMain(isCMSU); } @Override protected void onResume() { super.onResume(); isCMSU = SuVersionBool(Tools.SuVersion(MainContext)); if (upMain && isCMSU) UpdateMain(isCMSU); else this.onCreate(null); } @Override public void onPause() { super.onPause(); if (SuVersionBool(Tools.SuVersion(MainContext)) && Tools.getBoolean("isu_notification", false, MainContext)) { try { MainContext.unregisterReceiver(updateMainReceiver); } catch (IllegalArgumentException ignored) { } } } protected void UpdateMain(boolean CMSU) { if (CMSU) { suSwitch.setChecked(Tools.SuBinary(xbin_su)); SuStatus.setText( (suSwitch.isChecked() ? getString(R.string.activated) : getString(R.string.deactivated))); suSwitch.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { iSuSwitch(isChecked); } }); SuSwitchSummary.setText(getString(R.string.su_state)); // Selinux switch SelinuxSwitch.setChecked(Tools.isSELinuxActive()); SelinuxSwitch.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { SelinuxSwitch(isChecked); } }); per_app.setOnClickListener(new View.OnClickListener() { Intent myIntent = new Intent(getApplicationContext(), PerAppActivity.class); @Override public void onClick(View v) { startActivity(myIntent); } }); iSuNotification.setChecked(Tools.getBoolean("isu_notification", false, MainContext)); iSuNotification.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { Tools.saveBoolean("isu_notification", isChecked, MainContext); } }); SuSelinuxSwitch.setChecked(Tools.getBoolean("main_restart_selinux", false, MainContext)); SuSelinuxSwitch.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { Tools.saveBoolean("main_restart_selinux", isChecked, MainContext); } }); if (Tools.getBoolean("isu_notification", false, MainContext)) { try { MainContext.registerReceiver(updateMainReceiver, new IntentFilter("updateMainReceiver")); } catch (NullPointerException ignored) { } } upMain = true; } else { suSwitch.setEnabled(false); suSwitch.setTextColor(getColorWrapper(MainContext, R.color.text_gray)); suSwitch.setPaintFlags(suSwitch.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); SuSwitchSummary.setText(getString(R.string.su_not_cm)); su_version.setVisibility(View.GONE); SelinuxSwitch.setEnabled(false); SelinuxSwitch.setTextColor(getColorWrapper(MainContext, R.color.text_gray)); SelinuxSwitch.setPaintFlags(suSwitch.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); SuSelinuxSwitch.setEnabled(false); SuSelinuxSwitch.setTextColor(getColorWrapper(MainContext, R.color.text_gray)); SuSelinuxSwitch.setPaintFlags(suSwitch.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); iSuNotification.setEnabled(false); iSuNotification.setTextColor(getColorWrapper(MainContext, R.color.text_gray)); iSuNotification.setPaintFlags(suSwitch.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); SuSelinuxSwitchSummary.setVisibility(View.GONE); per_app.setEnabled(false); per_app_summary.setText(getString(R.string.not_available)); SuStatus.setVisibility(View.GONE); kernel_check.setTextColor(getColorWrapper(MainContext, R.color.colorAccent)); kernel_check.setText(getString(R.string.isu_kernel_no_su)); upMain = false; } } private final BroadcastReceiver updateMainReceiver = new BroadcastReceiver() { @Override public void onReceive(Context arg0, Intent intent) { UpdateMain(true); } }; public void Sepolicy() { String executableFilePath = getFilesDir().getPath() + "/"; if (!Tools.NewexistFile(executableFilePath + "libsupol.so", true) || !Tools.NewexistFile(executableFilePath + "supolicy", true)) { extractAssets(executableFilePath + "libsupol.so", "libsupol.so"); extractAssets(executableFilePath + "supolicy", "supolicy"); } Tools.PatchSepolicy(executableFilePath); } public void extractAssets(String executableFilePath, String filename) { AssetManager assetManager = getAssets(); InputStream inStream = null; OutputStream outStream = null; try { inStream = assetManager.open(filename); outStream = new FileOutputStream(executableFilePath); // for override file content //outStream = new FileOutputStream(out,true); // for append file content byte[] buffer = new byte[1024]; int length; while ((length = inStream.read(buffer)) > 0) { outStream.write(buffer, 0, length); } if (inStream != null) inStream.close(); if (outStream != null) outStream.close(); } catch (IOException e) { Log.e(TAG, "Failed to copy asset file: " + filename, e); } File execFile = new File(executableFilePath); execFile.setExecutable(true); Log.e(TAG, "Copy success: " + filename); } private void iSuSwitch(boolean isChecked) { Tools.SwitchSu(isChecked, MainContext); if (isChecked) SuStatus.setText( (Tools.SuBinary(xbin_su) ? getString(R.string.activated) : getString(R.string.su_change_fail))); else { SuStatus.setText((Tools.SuBinary(xbin_isu) ? getString(R.string.deactivated) : getString(R.string.su_change_fail))); if (!Tools.isSELinuxActive()) { Tools.SwitchSelinux(true); Tools.DoAToast("iSu " + (Tools.isSELinuxActive() ? getString(R.string.selinux_toast_ok) : getString(R.string.selinux_toast_nok)), MainContext); Selinux_State.setText(Tools.getSELinuxStatus()); SelinuxSwitch.setChecked(Tools.isSELinuxActive()); } if (Tools.getBoolean("isu_notification", false, MainContext)) Tools.DoNotification(MainContext); } } private void SelinuxSwitch(boolean isChecked) { Tools.SwitchSelinux(isChecked); Selinux_State.setText(Tools.getSELinuxStatus()); } private static int getColorWrapper(Context context, int id) { return ContextCompat.getColor(context, id); } private boolean SuVersionBool(String suVersion) { if (suVersion.contains("cm-su") || suVersion.contains("mk-su") || suVersion.contains("16 com.android.settings")) return true; else return false; } private boolean RebootSupport() { if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) { String executableFilePath = getFilesDir().getPath() + "/"; if (Tools.ReadSystemPatch()) return true; if (!Tools.NewexistFile(executableFilePath + "isush", true) || !Tools.NewexistFile(executableFilePath + "superuser.rc", true)) { extractAssets(executableFilePath + "isush", "isush"); extractAssets(executableFilePath + "superuser.rc", "superuser.rc"); } Tools.SystemPatch(executableFilePath); if (Tools.ReadSystemPatch()) return true; } return false; } }