Add root fragment and refactor

This commit is contained in:
topjohnwu 2016-08-23 05:18:28 +08:00
parent 36c575023e
commit 7bf83371d5
12 changed files with 92 additions and 104 deletions

View File

@ -12,13 +12,6 @@
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/AppTheme" android:theme="@style/AppTheme"
tools:ignore="AllowBackup,GoogleAppIndexingWarning"> tools:ignore="AllowBackup,GoogleAppIndexingWarning">
<!--<activity android:name=".ui.MainActivity">-->
<!--<intent-filter>-->
<!--<action android:name="android.intent.action.MAIN"/>-->
<!--<category android:name="android.intent.category.LAUNCHER"/>-->
<!--</intent-filter>-->
<!--</activity>-->
<activity <activity
android:name=".WelcomeActivity" android:name=".WelcomeActivity"
android:configChanges="orientation|screenSize"> android:configChanges="orientation|screenSize">

View File

@ -1,4 +1,4 @@
package com.topjohnwu.magisk.ui; package com.topjohnwu.magisk;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
@ -11,7 +11,7 @@ import android.view.ViewGroup;
import android.widget.CheckBox; import android.widget.CheckBox;
import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.model.Module; import com.topjohnwu.magisk.module.Module;
import com.topjohnwu.magisk.rv.ItemClickListener; import com.topjohnwu.magisk.rv.ItemClickListener;
import com.topjohnwu.magisk.rv.ModulesAdapter; import com.topjohnwu.magisk.rv.ModulesAdapter;

View File

@ -1,4 +1,4 @@
package com.topjohnwu.magisk.ui; package com.topjohnwu.magisk;
import android.Manifest; import android.Manifest;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
@ -26,7 +26,7 @@ import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.ui.utils.Utils; import com.topjohnwu.magisk.WelcomeActivity;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.File; import java.io.File;
@ -234,7 +234,7 @@ public class LogFragment extends Fragment {
protected String doInBackground(File... log) { protected String doInBackground(File... log) {
// Ensure initialize is done // Ensure initialize is done
try { try {
Utils.initialize.get(); WelcomeActivity.initialize.get();
} catch (InterruptedException | ExecutionException e) { } catch (InterruptedException | ExecutionException e) {
e.printStackTrace(); e.printStackTrace();
} }

View File

@ -1,4 +1,4 @@
package com.topjohnwu.magisk.ui; package com.topjohnwu.magisk;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
@ -13,9 +13,7 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.module.Module;
import com.topjohnwu.magisk.model.Module;
import com.topjohnwu.magisk.ui.utils.Utils;
import java.io.File; import java.io.File;
import java.io.FileFilter; import java.io.FileFilter;
@ -31,7 +29,7 @@ public class ModulesFragment extends Fragment {
private static final String MAGISK_PATH = "/magisk"; private static final String MAGISK_PATH = "/magisk";
private static final String MAGISK_CACHE_PATH = "/cache/magisk"; private static final String MAGISK_CACHE_PATH = "/cache/magisk";
private static List<Module> listModulesNoCache = new ArrayList<>(); private static List<Module> listModules = new ArrayList<>();
private static List<Module> listModulesCache = new ArrayList<>(); private static List<Module> listModulesCache = new ArrayList<>();
@BindView(R.id.progressBar) ProgressBar progressBar; @BindView(R.id.progressBar) ProgressBar progressBar;
@ -42,8 +40,8 @@ public class ModulesFragment extends Fragment {
public void onCreate(@Nullable Bundle savedInstanceState) { public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
listModules.clear();
listModulesCache.clear(); listModulesCache.clear();
listModulesNoCache.clear();
} }
@Nullable @Nullable
@ -60,11 +58,11 @@ public class ModulesFragment extends Fragment {
return view; return view;
} }
public static class NoCacheModuleFragment extends BaseModuleFragment { public static class NormalModuleFragment extends BaseModuleFragment {
@Override @Override
protected List<Module> listModules() { protected List<Module> listModules() {
return listModulesNoCache; return listModules;
} }
} }
@ -78,13 +76,13 @@ public class ModulesFragment extends Fragment {
} }
private class CheckFolders extends AsyncTask<Void, Integer, Boolean> { private class CheckFolders extends AsyncTask<Void, Integer, Void> {
@Override @Override
protected Boolean doInBackground(Void... voids) { protected Void doInBackground(Void... voids) {
// Ensure initialize is done // Ensure initialize is done
try { try {
Utils.initialize.get(); WelcomeActivity.initialize.get();
} catch (InterruptedException | ExecutionException e) { } catch (InterruptedException | ExecutionException e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -109,7 +107,7 @@ public class ModulesFragment extends Fragment {
if (m.isValid()) { if (m.isValid()) {
try { try {
m.parse(); m.parse();
listModulesNoCache.add(m); listModules.add(m);
} catch (Exception ignored) { } catch (Exception ignored) {
} }
} }
@ -129,12 +127,12 @@ public class ModulesFragment extends Fragment {
} }
} }
return true; return null;
} }
@Override @Override
protected void onPostExecute(Boolean result) { protected void onPostExecute(Void v) {
super.onPostExecute(result); super.onPostExecute(v);
progressBar.setVisibility(View.GONE); progressBar.setVisibility(View.GONE);
} }
@ -143,7 +141,7 @@ public class ModulesFragment extends Fragment {
private class TabsAdapter extends FragmentPagerAdapter { private class TabsAdapter extends FragmentPagerAdapter {
String[] tabTitles = new String[]{ String[] tabTitles = new String[]{
"_no_cache", "_cache" "Modules", "Cache Modules"
// TODO stringify // TODO stringify
}; };
@ -164,7 +162,7 @@ public class ModulesFragment extends Fragment {
@Override @Override
public Fragment getItem(int position) { public Fragment getItem(int position) {
if (position == 0) { if (position == 0) {
return new NoCacheModuleFragment(); return new NormalModuleFragment();
} else { } else {
return new CacheModuleFragment(); return new CacheModuleFragment();
} }

View File

@ -1,44 +1,45 @@
package com.topjohnwu.magisk.ui; package com.topjohnwu.magisk;
import android.app.Activity;
import android.graphics.Color; import android.graphics.Color;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton; import android.widget.CompoundButton;
import android.widget.Switch; import android.widget.Switch;
import android.widget.TextView; import android.widget.TextView;
import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.utils.Utils;
import java.io.File; import java.io.File;
import static com.topjohnwu.magisk.ui.utils.Utils.su; public class RootFragment extends Fragment {
public class MainActivity extends Activity {
private Switch rootToggle, selinuxToggle; private Switch rootToggle, selinuxToggle;
private TextView magiskVersion, rootStatus, selinuxStatus, safetyNet, permissive; private TextView magiskVersion, rootStatus, selinuxStatus, safetyNet, permissive;
private String suPath;
@Nullable
@Override @Override
protected void onCreate(Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState); View view = inflater.inflate(R.layout.root_fragment, container, false);
setContentView(R.layout.activity_main);
magiskVersion = (TextView) findViewById(R.id.magisk_version); magiskVersion = (TextView) view.findViewById(R.id.magisk_version);
rootToggle = (Switch) findViewById(R.id.root_toggle); rootToggle = (Switch) view.findViewById(R.id.root_toggle);
selinuxToggle = (Switch) findViewById(R.id.selinux_toggle); selinuxToggle = (Switch) view.findViewById(R.id.selinux_toggle);
rootStatus = (TextView) findViewById(R.id.root_status); rootStatus = (TextView) view.findViewById(R.id.root_status);
selinuxStatus = (TextView) findViewById(R.id.selinux_status); selinuxStatus = (TextView) view.findViewById(R.id.selinux_status);
safetyNet = (TextView) findViewById(R.id.safety_net); safetyNet = (TextView) view.findViewById(R.id.safety_net);
permissive = (TextView) findViewById(R.id.permissive); permissive = (TextView) view.findViewById(R.id.permissive);
suPath = su("getprop magisk.supath");
updateStatus(); updateStatus();
rootToggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { rootToggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override @Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) { public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
su(b ? "setprop magisk.root 1" : "setprop magisk.root 0"); Utils.su(b ? "setprop magisk.root 1" : "setprop magisk.root 0");
updateStatus(); updateStatus();
} }
}); });
@ -46,18 +47,19 @@ public class MainActivity extends Activity {
selinuxToggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { selinuxToggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override @Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) { public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
su(b ? "setenforce 1" : "setenforce 0"); Utils.su(b ? "setenforce 1" : "setenforce 0");
updateStatus(); updateStatus();
} }
}); });
//findViewById(R.id.modules).setOnClickListener(view -> startActivity(new Intent(this, ModulesActivity.class))); return view;
} }
private void updateStatus() { private void updateStatus() {
String selinux = su("getenforce"); String selinux = Utils.sh("getenforce");
String version = Utils.sh("getprop magisk.version");
magiskVersion.setText(getString(R.string.magisk_version, su("getprop magisk.version"))); magiskVersion.setText(getString(R.string.magisk_version, version));
selinuxStatus.setText(selinux); selinuxStatus.setText(selinux);
if (selinux.equals("Enforcing")) { if (selinux.equals("Enforcing")) {
@ -82,7 +84,7 @@ public class MainActivity extends Activity {
safetyNet.setTextColor(Color.RED); safetyNet.setTextColor(Color.RED);
rootToggle.setChecked(true); rootToggle.setChecked(true);
if (!new File(suPath + "/su").exists()) { if (!Utils.rootAccess) {
rootStatus.setText(R.string.root_system); rootStatus.setText(R.string.root_system);
safetyNet.setText(R.string.root_system_info); safetyNet.setText(R.string.root_system_info);
rootToggle.setEnabled(false); rootToggle.setEnabled(false);
@ -96,7 +98,7 @@ public class MainActivity extends Activity {
safetyNet.setTextColor(Color.GREEN); safetyNet.setTextColor(Color.GREEN);
rootToggle.setChecked(false); rootToggle.setChecked(false);
if (!new File(suPath + "/su").exists()) { if (!Utils.rootAccess) {
rootStatus.setText(R.string.root_none); rootStatus.setText(R.string.root_none);
safetyNet.setText(R.string.root_none_info); safetyNet.setText(R.string.root_none_info);
rootToggle.setEnabled(false); rootToggle.setEnabled(false);
@ -107,5 +109,4 @@ public class MainActivity extends Activity {
} }
} }
} }
} }

View File

@ -1,11 +1,13 @@
package com.topjohnwu.magisk; package com.topjohnwu.magisk;
import android.os.AsyncTask;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.support.annotation.IdRes; import android.support.annotation.IdRes;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.design.widget.NavigationView; import android.support.design.widget.NavigationView;
import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction; import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.GravityCompat; import android.support.v4.view.GravityCompat;
@ -16,10 +18,7 @@ import android.support.v7.widget.Toolbar;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import com.topjohnwu.magisk.ui.LogFragment; import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.magisk.ui.ModulesFragment;
import com.topjohnwu.magisk.ui.RootFragment;
import com.topjohnwu.magisk.ui.utils.Utils;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
@ -28,6 +27,8 @@ public class WelcomeActivity extends AppCompatActivity implements NavigationView
private static final String SELECTED_ITEM_ID = "SELECTED_ITEM_ID"; private static final String SELECTED_ITEM_ID = "SELECTED_ITEM_ID";
private final Handler mDrawerHandler = new Handler(); private final Handler mDrawerHandler = new Handler();
public static Init initialize = new Init();
public static View view;
@BindView(R.id.toolbar) Toolbar toolbar; @BindView(R.id.toolbar) Toolbar toolbar;
@BindView(R.id.drawer_layout) DrawerLayout drawer; @BindView(R.id.drawer_layout) DrawerLayout drawer;
@ -36,16 +37,40 @@ public class WelcomeActivity extends AppCompatActivity implements NavigationView
@IdRes @IdRes
private int mSelectedId = R.id.modules;// for now private int mSelectedId = R.id.modules;// for now
public static class Init extends AsyncTask<Void, Integer, Void> {
@Override
protected Void doInBackground(Void... voids) {
// Check root access
Utils.checkRoot();
// Permission for java code to read /cache files
if (Utils.rootAccess) {
Utils.su("chmod 755 /cache", "chmod 644 /cache/magisk.log");
}
return null;
}
@Override
protected void onPostExecute(Void v) {
super.onPostExecute(v);
if (!Utils.rootAccess) {
Snackbar.make(view, R.string.no_root_access, Snackbar.LENGTH_LONG).show();
}
}
}
@Override @Override
protected void onCreate(final Bundle savedInstanceState) { protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_welcome); setContentView(R.layout.activity_welcome);
view = findViewById(R.id.toolbar);
ButterKnife.bind(this); ButterKnife.bind(this);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
} }
Utils.initialize.execute(); initialize.execute();
setSupportActionBar(toolbar); setSupportActionBar(toolbar);

View File

@ -1,6 +1,6 @@
package com.topjohnwu.magisk.model; package com.topjohnwu.magisk.module;
import com.topjohnwu.magisk.ui.utils.Utils; import com.topjohnwu.magisk.utils.Utils;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.File; import java.io.File;

View File

@ -10,7 +10,8 @@ import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.model.Module; import com.topjohnwu.magisk.module.Module;
import com.topjohnwu.magisk.utils.Utils;
import java.util.List; import java.util.List;
@ -92,6 +93,10 @@ public class ModulesAdapter extends RecyclerView.Adapter<ModulesAdapter.ViewHold
public ViewHolder(View itemView) { public ViewHolder(View itemView) {
super(itemView); super(itemView);
ButterKnife.bind(this, itemView); ButterKnife.bind(this, itemView);
if (!Utils.rootAccess) {
checkBox.setEnabled(false);
delete.setEnabled(false);
}
} }
} }
} }

View File

@ -1,6 +0,0 @@
package com.topjohnwu.magisk.ui;
import android.support.v4.app.Fragment;
public class RootFragment extends Fragment {
}

View File

@ -1,30 +1,12 @@
package com.topjohnwu.magisk.ui.utils; package com.topjohnwu.magisk.utils;
import android.os.AsyncTask;
import java.util.List; import java.util.List;
import eu.chainfire.libsuperuser.Shell; import eu.chainfire.libsuperuser.Shell;
public class Utils { public class Utils {
public static final String suPath = sh("getprop magisk.supath"); public static final String suPath = sh("getprop magisk.supath");
public static boolean rootAccess = false; public static boolean rootAccess = false;
public static Init initialize = new Init();
public static class Init extends AsyncTask<Void, Integer, Void> {
@Override
protected Void doInBackground(Void... voids) {
// Check root access
rootAccess = isRoot();
// Permission for java code to read /cache files
if (rootAccess) {
su("chmod 755 /cache", "chmod 644 /cache/magisk.log");
}
return null;
}
}
public static String sh(String... commands) { public static String sh(String... commands) {
List<String> result = Shell.SH.run(commands); List<String> result = Shell.SH.run(commands);
@ -48,30 +30,27 @@ public class Utils {
return builder.toString(); return builder.toString();
} }
public static boolean isRoot() { public static void checkRoot() {
String [] availableTestCommands = new String[] {"echo -BOC-", "id"}; String [] availableTestCommands = new String[] {"echo -BOC-", "id"};
List<String> ret = Shell.run(Utils.suPath + "/su", availableTestCommands, null, false); List<String> ret = Shell.run(Utils.suPath + "/su", availableTestCommands, null, false);
if (ret == null) if (ret == null)
return false; return;
// Taken from libsuperuser // Taken from libsuperuser
// this is only one of many ways this can be done // this is only one of many ways this can be done
boolean echo_seen = false;
for (String line : ret) { for (String line : ret) {
if (line.contains("uid=")) { if (line.contains("uid=")) {
// id command is working, let's see if we are actually root // id command is working, let's see if we are actually root
return line.contains("uid=0"); rootAccess = line.contains("uid=0");
} else if (line.contains("-BOC-")) { } else if (line.contains("-BOC-")) {
// if we end up here, at least the su command starts some kind // if we end up here, at least the su command starts some kind
// of shell, let's hope it has root privileges - no way to know without // of shell, let's hope it has root privileges - no way to know without
// additional native binaries // additional native binaries
echo_seen = true; rootAccess = true;
} }
} }
return echo_seen;
} }
} }

View File

@ -3,8 +3,8 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:focusableInTouchMode="true" android:layout_marginTop="?attr/actionBarSize"
tools:context=".ui.MainActivity"> android:focusableInTouchMode="true">
<TextView <TextView
android:id="@+id/magisk_label" android:id="@+id/magisk_label"
@ -120,12 +120,4 @@
android:text="@string/selinux_toggle" android:text="@string/selinux_toggle"
android:textSize="20sp"/> android:textSize="20sp"/>
<Button
android:id="@+id/modules"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true"
android:text="modules activity"/>
</RelativeLayout> </RelativeLayout>

View File

@ -28,6 +28,7 @@
<string name="log">Log</string> <string name="log">Log</string>
<string name="remove">Remove</string> <string name="remove">Remove</string>
<string name="disable">Disable</string> <string name="disable">Disable</string>
<string name="no_root_access">No root access, functionality limited</string>
<string name="remove_file_created">Module will be removed at next reboot</string> <string name="remove_file_created">Module will be removed at next reboot</string>
<string name="disable_file_created">Module will be disabled at next reboot</string> <string name="disable_file_created">Module will be disabled at next reboot</string>
<string name="menuSaveToSd">Save to SD</string> <string name="menuSaveToSd">Save to SD</string>