mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-06-12 21:27:41 +02:00
Add status fragment
This commit is contained in:
71
app/src/main/java/com/topjohnwu/magisk/InstallFragment.java
Normal file
71
app/src/main/java/com/topjohnwu/magisk/InstallFragment.java
Normal file
@ -0,0 +1,71 @@
|
||||
package com.topjohnwu.magisk;
|
||||
|
||||
import android.app.Fragment;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.topjohnwu.magisk.receivers.DownloadReceiver;
|
||||
import com.topjohnwu.magisk.utils.Async;
|
||||
import com.topjohnwu.magisk.utils.Shell;
|
||||
import com.topjohnwu.magisk.utils.Utils;
|
||||
import com.topjohnwu.magisk.utils.ZipUtils;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import butterknife.ButterKnife;
|
||||
|
||||
// Currently empty, placing some code that we be used in the future
|
||||
public class InstallFragment extends Fragment {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View v = inflater.inflate(R.layout.install_fragment, container, false);
|
||||
ButterKnife.bind(this, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
getActivity().setTitle(R.string.install);
|
||||
}
|
||||
|
||||
private AlertDialog.OnClickListener flashMagisk = (dialogInterface, i) -> Utils.dlAndReceive(
|
||||
getActivity(),
|
||||
new DownloadReceiver() {
|
||||
@Override
|
||||
public void task(Uri uri) {
|
||||
new Async.FlashZIP(mContext, uri, mFilename) {
|
||||
@Override
|
||||
protected boolean unzipAndCheck() {
|
||||
publishProgress(mContext.getString(R.string.zip_install_unzip_zip_msg));
|
||||
if (Shell.rootAccess()) {
|
||||
// We might not have busybox yet, unzip with Java
|
||||
// We will have complete busybox after Magisk installation
|
||||
ZipUtils.unzip(mCachedFile, new File(mCachedFile.getParent(), "magisk"));
|
||||
Shell.su(
|
||||
"mkdir -p " + Async.TMP_FOLDER_PATH + "/magisk",
|
||||
"cp -af " + mCachedFile.getParent() + "/magisk/. " + Async.TMP_FOLDER_PATH + "/magisk"
|
||||
);
|
||||
}
|
||||
super.unzipAndCheck();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void done() {
|
||||
Shell.su("setprop magisk.version " + String.valueOf(StatusFragment.remoteMagiskVersion));
|
||||
super.done();
|
||||
}
|
||||
}.exec();
|
||||
}
|
||||
},
|
||||
StatusFragment.magiskLink,
|
||||
"Magisk-v" + String.valueOf(StatusFragment.remoteMagiskVersion) + ".zip");
|
||||
}
|
@ -67,6 +67,7 @@ public class LogFragment extends Fragment {
|
||||
super.onResume();
|
||||
setHasOptionsMenu(true);
|
||||
new LogManager().read();
|
||||
getActivity().setTitle(R.string.log);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,300 +0,0 @@
|
||||
package com.topjohnwu.magisk;
|
||||
|
||||
import android.app.Fragment;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.content.FileProvider;
|
||||
import android.support.v4.widget.SwipeRefreshLayout;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.topjohnwu.magisk.receivers.DownloadReceiver;
|
||||
import com.topjohnwu.magisk.utils.Async;
|
||||
import com.topjohnwu.magisk.utils.Logger;
|
||||
import com.topjohnwu.magisk.utils.Shell;
|
||||
import com.topjohnwu.magisk.utils.Utils;
|
||||
import com.topjohnwu.magisk.utils.ZipUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
import butterknife.BindColor;
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
|
||||
public class MagiskFragment extends Fragment {
|
||||
|
||||
public static int remoteAppVersionCode = -1;
|
||||
public static double magiskVersion, remoteMagiskVersion = -1;
|
||||
public static String magiskVersionString, magiskLink, magiskChangelog, appLink, appChangelog, remoteAppVersion;
|
||||
|
||||
@BindView(R.id.swipeRefreshLayout) SwipeRefreshLayout mSwipeRefreshLayout;
|
||||
|
||||
@BindView(R.id.magiskStatusView) View magiskStatusView;
|
||||
@BindView(R.id.magisk_status_container) View magiskStatusContainer;
|
||||
@BindView(R.id.magisk_status_icon) ImageView magiskStatusIcon;
|
||||
@BindView(R.id.magisk_version) TextView magiskVersionText;
|
||||
|
||||
@BindView(R.id.app_updateView) View appUpdateView;
|
||||
@BindView(R.id.app_check_updates_container) View appCheckUpdatesContainer;
|
||||
@BindView(R.id.app_check_updates_icon) ImageView appCheckUpdatesIcon;
|
||||
@BindView(R.id.app_check_updates_status) TextView appCheckUpdatesStatus;
|
||||
@BindView(R.id.app_check_updates_progress) ProgressBar appCheckUpdatesProgress;
|
||||
|
||||
@BindView(R.id.magisk_updateView) View magiskUpdateView;
|
||||
@BindView(R.id.magisk_check_updates_container) View magiskCheckUpdatesContainer;
|
||||
@BindView(R.id.magisk_check_updates_icon) ImageView magiskCheckUpdatesIcon;
|
||||
@BindView(R.id.magisk_check_updates_status) TextView magiskCheckUpdatesStatus;
|
||||
@BindView(R.id.magisk_check_updates_progress) ProgressBar magiskCheckUpdatesProgress;
|
||||
|
||||
@BindColor(R.color.green500) int colorOK;
|
||||
@BindColor(R.color.yellow500) int colorWarn;
|
||||
@BindColor(R.color.grey500) int colorNeutral;
|
||||
@BindColor(R.color.blue500) int colorInfo;
|
||||
|
||||
@BindColor(android.R.color.transparent) int trans;
|
||||
|
||||
int statusOK = R.drawable.ic_check_circle;
|
||||
int statusUnknown = R.drawable.ic_help;
|
||||
|
||||
private AlertDialog.Builder builder;
|
||||
|
||||
private SharedPreferences prefs;
|
||||
private SharedPreferences.OnSharedPreferenceChangeListener listener;
|
||||
|
||||
private AlertDialog.OnClickListener flashMagisk = (dialogInterface, i) -> Utils.dlAndReceive(
|
||||
getActivity(),
|
||||
new DownloadReceiver() {
|
||||
@Override
|
||||
public void task(Uri uri) {
|
||||
new Async.FlashZIP(mContext, uri, mFilename) {
|
||||
@Override
|
||||
protected boolean unzipAndCheck() {
|
||||
publishProgress(mContext.getString(R.string.zip_install_unzip_zip_msg));
|
||||
if (Shell.rootAccess()) {
|
||||
// We might not have busybox yet, unzip with Java
|
||||
// We will have complete busybox after Magisk installation
|
||||
ZipUtils.unzip(mCachedFile, new File(mCachedFile.getParent(), "magisk"));
|
||||
Shell.su(
|
||||
"mkdir -p " + Async.TMP_FOLDER_PATH + "/magisk",
|
||||
"cp -af " + mCachedFile.getParent() + "/magisk/. " + Async.TMP_FOLDER_PATH + "/magisk"
|
||||
);
|
||||
}
|
||||
super.unzipAndCheck();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void done() {
|
||||
Shell.su("setprop magisk.version " + String.valueOf(remoteMagiskVersion));
|
||||
super.done();
|
||||
}
|
||||
}.exec();
|
||||
}
|
||||
},
|
||||
magiskLink,
|
||||
"Magisk-v" + String.valueOf(remoteMagiskVersion) + ".zip");
|
||||
|
||||
private AlertDialog.OnClickListener installMagiskApk = (dialogInterface, i) -> Utils.dlAndReceive(
|
||||
getActivity(),
|
||||
new DownloadReceiver() {
|
||||
@Override
|
||||
public void task(Uri uri) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
Intent install = new Intent(Intent.ACTION_INSTALL_PACKAGE);
|
||||
install.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
Uri content = FileProvider.getUriForFile(getActivity(), "com.topjohnwu.magisk.provider", new File(uri.getPath()));
|
||||
install.setData(content);
|
||||
mContext.startActivity(install);
|
||||
} else {
|
||||
Intent install = new Intent(Intent.ACTION_VIEW);
|
||||
install.setDataAndType(uri, "application/vnd.android.package-archive");
|
||||
install.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
mContext.startActivity(install);
|
||||
}
|
||||
}
|
||||
},
|
||||
appLink,
|
||||
"MagiskManager-v" + remoteAppVersion + ".apk");
|
||||
|
||||
static {
|
||||
updateMagiskVersion();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
View v = inflater.inflate(R.layout.magisk_fragment, container, false);
|
||||
ButterKnife.bind(this, v);
|
||||
|
||||
prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
|
||||
|
||||
mSwipeRefreshLayout.setOnRefreshListener(() -> {
|
||||
prefs.edit().putBoolean("update_check_done", false).apply();
|
||||
|
||||
appCheckUpdatesContainer.setBackgroundColor(trans);
|
||||
magiskCheckUpdatesContainer.setBackgroundColor(trans);
|
||||
|
||||
appCheckUpdatesIcon.setImageResource(0);
|
||||
magiskCheckUpdatesIcon.setImageResource(0);
|
||||
|
||||
appCheckUpdatesStatus.setText(null);
|
||||
magiskCheckUpdatesStatus.setText(null);
|
||||
|
||||
appCheckUpdatesProgress.setVisibility(View.VISIBLE);
|
||||
magiskCheckUpdatesProgress.setVisibility(View.VISIBLE);
|
||||
|
||||
new Async.CheckUpdates(prefs).exec();
|
||||
});
|
||||
|
||||
if (prefs.getBoolean("update_check_done", false)) {
|
||||
updateUI();
|
||||
}
|
||||
|
||||
listener = (pref, s) -> {
|
||||
if (s.equals("update_check_done")) {
|
||||
if (pref.getBoolean(s, false)) {
|
||||
Logger.dev("MagiskFragment: UI refresh triggered");
|
||||
updateMagiskVersion();
|
||||
updateUI();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
prefs.registerOnSharedPreferenceChangeListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
prefs.unregisterOnSharedPreferenceChangeListener(listener);
|
||||
}
|
||||
|
||||
private static void updateMagiskVersion() {
|
||||
List<String> ret = Shell.sh("getprop magisk.version");
|
||||
if (ret.get(0).length() == 0) {
|
||||
magiskVersion = -1;
|
||||
} else try {
|
||||
magiskVersionString = ret.get(0);
|
||||
magiskVersion = Double.parseDouble(ret.get(0));
|
||||
} catch (NumberFormatException e) {
|
||||
// Custom version don't need to receive updates
|
||||
magiskVersion = Double.POSITIVE_INFINITY;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void updateUI() {
|
||||
String theme = prefs.getString("theme", "");
|
||||
if (theme.equals("Dark")) {
|
||||
builder = new AlertDialog.Builder(getActivity(), R.style.AlertDialog_dh);
|
||||
} else {
|
||||
builder = new AlertDialog.Builder(getActivity());
|
||||
}
|
||||
|
||||
if (magiskVersion == -1) {
|
||||
magiskStatusContainer.setBackgroundColor(colorNeutral);
|
||||
magiskStatusIcon.setImageResource(statusUnknown);
|
||||
|
||||
magiskVersionText.setTextColor(colorNeutral);
|
||||
magiskVersionText.setText(R.string.magisk_version_error);
|
||||
} else {
|
||||
magiskStatusContainer.setBackgroundColor(colorOK);
|
||||
magiskStatusIcon.setImageResource(statusOK);
|
||||
|
||||
magiskVersionText.setText(getString(R.string.magisk_version, magiskVersionString));
|
||||
magiskVersionText.setTextColor(colorOK);
|
||||
}
|
||||
|
||||
if (remoteMagiskVersion == -1) {
|
||||
appCheckUpdatesContainer.setBackgroundColor(colorWarn);
|
||||
magiskCheckUpdatesContainer.setBackgroundColor(colorWarn);
|
||||
|
||||
appCheckUpdatesIcon.setImageResource(R.drawable.ic_warning);
|
||||
magiskCheckUpdatesIcon.setImageResource(R.drawable.ic_warning);
|
||||
|
||||
appCheckUpdatesStatus.setText(R.string.cannot_check_updates);
|
||||
appCheckUpdatesStatus.setTextColor(colorWarn);
|
||||
magiskCheckUpdatesStatus.setText(R.string.cannot_check_updates);
|
||||
magiskCheckUpdatesStatus.setTextColor(colorWarn);
|
||||
} else {
|
||||
if (remoteMagiskVersion > magiskVersion) {
|
||||
magiskCheckUpdatesContainer.setBackgroundColor(colorInfo);
|
||||
magiskCheckUpdatesIcon.setImageResource(R.drawable.ic_file_download);
|
||||
magiskCheckUpdatesStatus.setText(getString(R.string.magisk_update_available, String.valueOf(remoteMagiskVersion)));
|
||||
magiskCheckUpdatesStatus.setTextColor(colorInfo);
|
||||
magiskUpdateView.setOnClickListener(view -> builder
|
||||
.setTitle(getString(R.string.update_title, getString(R.string.magisk)))
|
||||
.setMessage(getString(R.string.update_msg, getString(R.string.magisk), String.valueOf(remoteMagiskVersion), magiskChangelog))
|
||||
.setCancelable(true)
|
||||
.setPositiveButton(R.string.download_install, flashMagisk)
|
||||
.setNegativeButton(R.string.no_thanks, null)
|
||||
.show());
|
||||
|
||||
} else {
|
||||
magiskCheckUpdatesContainer.setBackgroundColor(colorOK);
|
||||
magiskCheckUpdatesIcon.setImageResource(R.drawable.ic_check_circle);
|
||||
magiskCheckUpdatesStatus.setText(getString(R.string.up_to_date, getString(R.string.magisk)));
|
||||
magiskCheckUpdatesStatus.setTextColor(colorOK);
|
||||
magiskUpdateView.setOnClickListener(view -> builder
|
||||
.setTitle(getString(R.string.repo_install_title, getString(R.string.magisk)))
|
||||
.setMessage(getString(R.string.repo_install_msg, "Magisk-v" + String.valueOf(remoteMagiskVersion)))
|
||||
.setCancelable(true)
|
||||
.setPositiveButton(R.string.download_install, flashMagisk)
|
||||
.setNegativeButton(R.string.no_thanks, null)
|
||||
.show());
|
||||
}
|
||||
|
||||
if (remoteAppVersionCode > BuildConfig.VERSION_CODE) {
|
||||
appCheckUpdatesContainer.setBackgroundColor(colorInfo);
|
||||
appCheckUpdatesIcon.setImageResource(R.drawable.ic_file_download);
|
||||
appCheckUpdatesStatus.setText(getString(R.string.app_update_available, remoteAppVersion));
|
||||
appCheckUpdatesStatus.setTextColor(colorInfo);
|
||||
appUpdateView.setOnClickListener(view -> builder
|
||||
.setTitle(getString(R.string.update_title, getString(R.string.app_name)))
|
||||
.setMessage(getString(R.string.update_msg, getString(R.string.app_name), remoteAppVersion, appChangelog))
|
||||
.setCancelable(true)
|
||||
.setPositiveButton(R.string.download_install, installMagiskApk)
|
||||
.setNegativeButton(R.string.no_thanks, null)
|
||||
.show()
|
||||
);
|
||||
} else {
|
||||
appCheckUpdatesContainer.setBackgroundColor(colorOK);
|
||||
appCheckUpdatesIcon.setImageResource(R.drawable.ic_check_circle);
|
||||
appCheckUpdatesStatus.setText(getString(R.string.up_to_date, getString(R.string.app_name)));
|
||||
appCheckUpdatesStatus.setTextColor(colorOK);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
appCheckUpdatesProgress.setVisibility(View.GONE);
|
||||
magiskCheckUpdatesProgress.setVisibility(View.GONE);
|
||||
mSwipeRefreshLayout.setRefreshing(false);
|
||||
|
||||
if (magiskVersion == -1) {
|
||||
builder
|
||||
.setTitle(R.string.no_magisk_title)
|
||||
.setMessage(R.string.no_magisk_msg)
|
||||
.setCancelable(true)
|
||||
.setPositiveButton(R.string.download_install, flashMagisk)
|
||||
.setNegativeButton(R.string.no_thanks, null)
|
||||
.show();
|
||||
}
|
||||
}
|
||||
}
|
@ -84,6 +84,7 @@ public class MagiskHideFragment extends Fragment {
|
||||
super.onResume();
|
||||
setHasOptionsMenu(true);
|
||||
mView = this.getView();
|
||||
getActivity().setTitle(R.string.magiskhide);
|
||||
}
|
||||
|
||||
private class LoadApps extends Async.RootTask<Void, Void, Void> {
|
||||
|
@ -37,10 +37,10 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
|
||||
|
||||
@BindView(R.id.toolbar) Toolbar toolbar;
|
||||
@BindView(R.id.drawer_layout) DrawerLayout drawer;
|
||||
@BindView(R.id.nav_view) NavigationView navigationView;
|
||||
@BindView(R.id.nav_view) public NavigationView navigationView;
|
||||
|
||||
@IdRes
|
||||
private int mSelectedId = R.id.magisk;
|
||||
private int mSelectedId = R.id.status;
|
||||
|
||||
@Override
|
||||
protected void onCreate(final Bundle savedInstanceState) {
|
||||
@ -59,10 +59,6 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
|
||||
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);
|
||||
}
|
||||
|
||||
if (!Shell.rootAccess()) {
|
||||
Snackbar.make(findViewById(android.R.id.content), R.string.no_root_access, Snackbar.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
setSupportActionBar(toolbar);
|
||||
|
||||
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close) {
|
||||
@ -125,7 +121,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
|
||||
|
||||
private void checkHideSection() {
|
||||
Menu menu = navigationView.getMenu();
|
||||
if (MagiskFragment.magiskVersion == -1) {
|
||||
if (StatusFragment.magiskVersion == -1) {
|
||||
menu.findItem(R.id.magiskhide).setVisible(false);
|
||||
menu.findItem(R.id.modules).setVisible(false);
|
||||
menu.findItem(R.id.downloads).setVisible(false);
|
||||
@ -141,28 +137,27 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
|
||||
Fragment navFragment = null;
|
||||
String tag = "";
|
||||
switch (itemId) {
|
||||
case R.id.magisk:
|
||||
setTitle(R.string.magisk);
|
||||
tag = "magisk";
|
||||
navFragment = new MagiskFragment();
|
||||
case R.id.status:
|
||||
tag = "status";
|
||||
navFragment = new StatusFragment();
|
||||
break;
|
||||
case R.id.install:
|
||||
tag = "install";
|
||||
navFragment = new InstallFragment();
|
||||
break;
|
||||
case R.id.modules:
|
||||
setTitle(R.string.modules);
|
||||
tag = "modules";
|
||||
navFragment = new ModulesFragment();
|
||||
break;
|
||||
case R.id.downloads:
|
||||
setTitle(R.string.downloads);
|
||||
tag = "downloads";
|
||||
navFragment = new ReposFragment();
|
||||
break;
|
||||
case R.id.magiskhide:
|
||||
setTitle(R.string.magiskhide);
|
||||
tag = "magiskhide";
|
||||
navFragment = new MagiskHideFragment();
|
||||
break;
|
||||
case R.id.log:
|
||||
setTitle(R.string.log);
|
||||
tag = "log";
|
||||
navFragment = new LogFragment();
|
||||
break;
|
||||
@ -179,8 +174,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
|
||||
transaction.setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out);
|
||||
try {
|
||||
transaction.replace(R.id.content_frame, navFragment, tag).commit();
|
||||
} catch (IllegalStateException ignored) {
|
||||
}
|
||||
} catch (IllegalStateException ignored) {}
|
||||
}
|
||||
}
|
||||
}
|
@ -92,6 +92,7 @@ public class ModulesFragment extends Fragment {
|
||||
super.onResume();
|
||||
mView = this.getView();
|
||||
prefs.registerOnSharedPreferenceChangeListener(listener);
|
||||
getActivity().setTitle(R.string.modules);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -114,6 +114,7 @@ public class ReposFragment extends Fragment {
|
||||
super.onResume();
|
||||
setHasOptionsMenu(true);
|
||||
prefs.registerOnSharedPreferenceChangeListener(listener);
|
||||
getActivity().setTitle(R.string.downloads);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -89,10 +89,10 @@ public class SettingsActivity extends AppCompatActivity {
|
||||
|
||||
themePreference.setSummary(themePreference.getValue());
|
||||
|
||||
if (MagiskFragment.magiskVersion < 9) {
|
||||
if (StatusFragment.magiskVersion < 9) {
|
||||
hostsPreference.setEnabled(false);
|
||||
busyboxPreference.setEnabled(false);
|
||||
} else if (MagiskFragment.magiskVersion < 8) {
|
||||
} else if (StatusFragment.magiskVersion < 8) {
|
||||
magiskhidePreference.setEnabled(false);
|
||||
} else {
|
||||
busyboxPreference.setEnabled(true);
|
||||
|
@ -5,11 +5,9 @@ import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.topjohnwu.magisk.utils.Async;
|
||||
import com.topjohnwu.magisk.utils.Logger;
|
||||
import com.topjohnwu.magisk.utils.SafetyNetHelper;
|
||||
import com.topjohnwu.magisk.utils.Utils;
|
||||
|
||||
public class SplashActivity extends AppCompatActivity {
|
||||
@ -38,24 +36,6 @@ public class SplashActivity extends AppCompatActivity {
|
||||
.putBoolean("hosts", Utils.itemExist(false, "/magisk/.core/hosts"))
|
||||
.apply();
|
||||
|
||||
// Simple POC for checking SN status
|
||||
new SafetyNetHelper(getApplicationContext()) {
|
||||
@Override
|
||||
public void handleResults(int i) {
|
||||
switch (i) {
|
||||
case -1:
|
||||
Toast.makeText(mContext, "SN: Error", Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
case 0:
|
||||
Toast.makeText(mContext, "SN: Fail", Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
case 1:
|
||||
Toast.makeText(mContext, "SN: Success", Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}.requestTest();
|
||||
|
||||
new Async.CheckUpdates(prefs).exec();
|
||||
|
||||
new Async.LoadModules(prefs) {
|
||||
|
267
app/src/main/java/com/topjohnwu/magisk/StatusFragment.java
Normal file
267
app/src/main/java/com/topjohnwu/magisk/StatusFragment.java
Normal file
@ -0,0 +1,267 @@
|
||||
package com.topjohnwu.magisk;
|
||||
|
||||
import android.app.Fragment;
|
||||
import android.app.FragmentTransaction;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.content.FileProvider;
|
||||
import android.support.v4.widget.SwipeRefreshLayout;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.topjohnwu.magisk.receivers.DownloadReceiver;
|
||||
import com.topjohnwu.magisk.utils.Async;
|
||||
import com.topjohnwu.magisk.utils.Logger;
|
||||
import com.topjohnwu.magisk.utils.SafetyNetHelper;
|
||||
import com.topjohnwu.magisk.utils.Shell;
|
||||
import com.topjohnwu.magisk.utils.Utils;
|
||||
import com.topjohnwu.magisk.utils.ZipUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
import butterknife.BindColor;
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
|
||||
public class StatusFragment extends Fragment {
|
||||
|
||||
public static int remoteAppVersionCode = -1;
|
||||
public static double magiskVersion, remoteMagiskVersion = -1;
|
||||
public static String magiskVersionString, magiskLink, magiskChangelog, appLink, appChangelog, remoteAppVersion;
|
||||
|
||||
private static int lastSNCheckResult = -1;
|
||||
|
||||
@BindView(R.id.swipeRefreshLayout) SwipeRefreshLayout mSwipeRefreshLayout;
|
||||
|
||||
@BindView(R.id.magisk_status_container) View magiskStatusContainer;
|
||||
@BindView(R.id.magisk_status_icon) ImageView magiskStatusIcon;
|
||||
@BindView(R.id.magisk_version) TextView magiskVersionText;
|
||||
@BindView(R.id.magisk_update_status) TextView magiskUpdateText;
|
||||
@BindView(R.id.magisk_check_updates_progress) ProgressBar magiskCheckUpdatesProgress;
|
||||
|
||||
@BindView(R.id.root_status_container) View rootStatusContainer;
|
||||
@BindView(R.id.root_status_icon) ImageView rootStatusIcon;
|
||||
@BindView(R.id.root_status) TextView rootStatusText;
|
||||
@BindView(R.id.root_info) TextView rootInfoText;
|
||||
|
||||
@BindView(R.id.safetyNet_container) View safetyNetContainer;
|
||||
@BindView(R.id.safetyNet_icon) ImageView safetyNetIcon;
|
||||
@BindView(R.id.safetyNet_status) TextView safetyNetStatusText;
|
||||
@BindView(R.id.safetyNet_check_progress) ProgressBar safetyNetProgress;
|
||||
|
||||
@BindColor(R.color.red500) int colorBad;
|
||||
@BindColor(R.color.green500) int colorOK;
|
||||
@BindColor(R.color.yellow500) int colorWarn;
|
||||
@BindColor(R.color.grey500) int colorNeutral;
|
||||
@BindColor(R.color.blue500) int colorInfo;
|
||||
@BindColor(android.R.color.transparent) int trans;
|
||||
|
||||
private AlertDialog.Builder builder;
|
||||
|
||||
private SharedPreferences prefs;
|
||||
private SharedPreferences.OnSharedPreferenceChangeListener listener;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
View v = inflater.inflate(R.layout.status_fragment, container, false);
|
||||
ButterKnife.bind(this, v);
|
||||
|
||||
prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
|
||||
|
||||
String theme = prefs.getString("theme", "");
|
||||
if (theme.equals("Dark")) {
|
||||
builder = new AlertDialog.Builder(getActivity(), R.style.AlertDialog_dh);
|
||||
} else {
|
||||
builder = new AlertDialog.Builder(getActivity());
|
||||
}
|
||||
|
||||
mSwipeRefreshLayout.setOnRefreshListener(() -> {
|
||||
prefs.edit().putBoolean("update_check_done", false).apply();
|
||||
|
||||
magiskStatusContainer.setBackgroundColor(trans);
|
||||
magiskStatusIcon.setImageResource(0);
|
||||
magiskUpdateText.setText(R.string.checking_for_updates);
|
||||
magiskCheckUpdatesProgress.setVisibility(View.VISIBLE);
|
||||
|
||||
new Async.CheckUpdates(prefs).exec();
|
||||
checkSafetyNet();
|
||||
});
|
||||
|
||||
listener = (pref, s) -> {
|
||||
if (s.equals("update_check_done")) {
|
||||
if (pref.getBoolean(s, false)) {
|
||||
Logger.dev("StatusFragment: UI refresh triggered");
|
||||
updateUI();
|
||||
updateCheckUI();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
updateUI();
|
||||
if (prefs.getBoolean("update_check_done", false)) {
|
||||
updateCheckUI();
|
||||
}
|
||||
if (lastSNCheckResult == -1) {
|
||||
checkSafetyNet();
|
||||
} else {
|
||||
updateSafetyNetUI();
|
||||
}
|
||||
|
||||
if (magiskVersion < 0) {
|
||||
builder
|
||||
.setTitle(R.string.no_magisk_title)
|
||||
.setMessage(R.string.no_magisk_msg)
|
||||
.setCancelable(true)
|
||||
.setPositiveButton(R.string.download_install, (dialogInterface, i) -> {
|
||||
((MainActivity) getActivity()).navigationView.setCheckedItem(R.id.install);
|
||||
FragmentTransaction transaction = getFragmentManager().beginTransaction();
|
||||
transaction.setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out);
|
||||
try {
|
||||
transaction.replace(R.id.content_frame, new InstallFragment(), "install").commit();
|
||||
} catch (IllegalStateException ignored) {}
|
||||
})
|
||||
.setNegativeButton(R.string.no_thanks, null)
|
||||
.show();
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
prefs.registerOnSharedPreferenceChangeListener(listener);
|
||||
getActivity().setTitle(R.string.status);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
prefs.unregisterOnSharedPreferenceChangeListener(listener);
|
||||
}
|
||||
|
||||
private void updateUI() {
|
||||
int image, color;
|
||||
|
||||
List<String> ret = Shell.sh("getprop magisk.version");
|
||||
if (ret.get(0).length() == 0) {
|
||||
magiskVersion = -1;
|
||||
magiskVersionText.setText(R.string.magisk_version_error);
|
||||
} else {
|
||||
try {
|
||||
magiskVersionString = ret.get(0);
|
||||
magiskVersion = Double.parseDouble(ret.get(0));
|
||||
} catch (NumberFormatException e) {
|
||||
// Custom version don't need to receive updates
|
||||
magiskVersion = Double.POSITIVE_INFINITY;
|
||||
}
|
||||
magiskVersionText.setText(getString(R.string.magisk_version, magiskVersionString));
|
||||
}
|
||||
|
||||
if (Shell.rootStatus == 1) {
|
||||
color = colorOK;
|
||||
image = R.drawable.ic_check_circle;
|
||||
rootStatusText.setText(R.string.proper_root);
|
||||
rootInfoText.setText(Shell.sh("su -v").get(0));
|
||||
|
||||
} else {
|
||||
rootInfoText.setText(R.string.root_info_warning);
|
||||
if (Shell.rootStatus == 0) {
|
||||
color = colorBad;
|
||||
image = R.drawable.ic_cancel;
|
||||
rootStatusText.setText(R.string.not_rooted);
|
||||
} else {
|
||||
color = colorNeutral;
|
||||
image = R.drawable.ic_help;
|
||||
rootStatusText.setText(R.string.root_error);
|
||||
}
|
||||
}
|
||||
rootStatusContainer.setBackgroundColor(color);
|
||||
rootStatusText.setTextColor(color);
|
||||
rootInfoText.setTextColor(color);
|
||||
rootStatusIcon.setImageResource(image);
|
||||
}
|
||||
|
||||
private void updateCheckUI() {
|
||||
int image, color;
|
||||
|
||||
if (remoteMagiskVersion < 0) {
|
||||
color = colorNeutral;
|
||||
image = R.drawable.ic_help;
|
||||
magiskUpdateText.setText(R.string.cannot_check_updates);
|
||||
} else if (remoteMagiskVersion > magiskVersion) {
|
||||
color = colorInfo;
|
||||
image = R.drawable.ic_update;
|
||||
magiskUpdateText.setText(getString(R.string.magisk_update_available, String.valueOf(remoteMagiskVersion)));
|
||||
} else {
|
||||
color = colorOK;
|
||||
image = R.drawable.ic_check_circle;
|
||||
magiskUpdateText.setText(getString(R.string.up_to_date, getString(R.string.magisk)));
|
||||
}
|
||||
|
||||
if (magiskVersion < 0) {
|
||||
color = colorBad;
|
||||
image = R.drawable.ic_cancel;
|
||||
}
|
||||
magiskStatusContainer.setBackgroundColor(color);
|
||||
magiskVersionText.setTextColor(color);
|
||||
magiskUpdateText.setTextColor(color);
|
||||
magiskStatusIcon.setImageResource(image);
|
||||
|
||||
magiskCheckUpdatesProgress.setVisibility(View.GONE);
|
||||
mSwipeRefreshLayout.setRefreshing(false);
|
||||
}
|
||||
|
||||
private void updateSafetyNetUI() {
|
||||
int image, color;
|
||||
safetyNetProgress.setVisibility(View.GONE);
|
||||
switch (lastSNCheckResult) {
|
||||
case -1:
|
||||
color = colorNeutral;
|
||||
image = R.drawable.ic_help;
|
||||
safetyNetStatusText.setText(R.string.safetyNet_error);
|
||||
break;
|
||||
case 0:
|
||||
color = colorBad;
|
||||
image = R.drawable.ic_cancel;
|
||||
safetyNetStatusText.setText(R.string.safetyNet_fail);
|
||||
break;
|
||||
case 1:
|
||||
default:
|
||||
color = colorOK;
|
||||
image = R.drawable.ic_check_circle;
|
||||
safetyNetStatusText.setText(R.string.safetyNet_pass);
|
||||
break;
|
||||
}
|
||||
safetyNetContainer.setBackgroundColor(color);
|
||||
safetyNetStatusText.setTextColor(color);
|
||||
safetyNetIcon.setImageResource(image);
|
||||
}
|
||||
|
||||
private void checkSafetyNet() {
|
||||
safetyNetProgress.setVisibility(View.VISIBLE);
|
||||
safetyNetContainer.setBackgroundColor(trans);
|
||||
safetyNetIcon.setImageResource(0);
|
||||
safetyNetStatusText.setText(R.string.checking_safetyNet_status);
|
||||
new SafetyNetHelper(getActivity()) {
|
||||
@Override
|
||||
public void handleResults(int i) {
|
||||
lastSNCheckResult = i;
|
||||
updateSafetyNetUI();
|
||||
}
|
||||
}.requestTest();
|
||||
}
|
||||
}
|
||||
|
@ -12,8 +12,8 @@ import android.support.v7.app.AlertDialog;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.topjohnwu.magisk.MagiskFragment;
|
||||
import com.topjohnwu.magisk.R;
|
||||
import com.topjohnwu.magisk.StatusFragment;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
@ -63,14 +63,14 @@ public class Async {
|
||||
JSONObject magisk = json.getJSONObject("magisk");
|
||||
JSONObject app = json.getJSONObject("app");
|
||||
|
||||
MagiskFragment.remoteMagiskVersion = magisk.getDouble("versionCode");
|
||||
MagiskFragment.magiskLink = magisk.getString("link");
|
||||
MagiskFragment.magiskChangelog = magisk.getString("changelog");
|
||||
StatusFragment.remoteMagiskVersion = magisk.getDouble("versionCode");
|
||||
StatusFragment.magiskLink = magisk.getString("link");
|
||||
StatusFragment.magiskChangelog = magisk.getString("changelog");
|
||||
|
||||
MagiskFragment.remoteAppVersion = app.getString("version");
|
||||
MagiskFragment.remoteAppVersionCode = app.getInt("versionCode");
|
||||
MagiskFragment.appLink = app.getString("link");
|
||||
MagiskFragment.appChangelog = app.getString("changelog");
|
||||
StatusFragment.remoteAppVersion = app.getString("version");
|
||||
StatusFragment.remoteAppVersionCode = app.getInt("versionCode");
|
||||
StatusFragment.appLink = app.getString("link");
|
||||
StatusFragment.appChangelog = app.getString("changelog");
|
||||
|
||||
} catch (JSONException ignored) {
|
||||
Logger.dev("JSON error!");
|
||||
|
@ -15,7 +15,6 @@ import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Arrays;
|
||||
|
||||
public abstract class SafetyNetHelper
|
||||
implements GoogleApiClient.OnConnectionFailedListener, GoogleApiClient.ConnectionCallbacks {
|
||||
|
Reference in New Issue
Block a user