mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-24 02:25:28 +00:00
Update SafetyNet
This commit is contained in:
parent
3e9174deed
commit
454abc388b
@ -1,51 +0,0 @@
|
||||
package com.topjohnwu.magisk.tasks;
|
||||
|
||||
import android.app.Activity;
|
||||
|
||||
import com.topjohnwu.magisk.App;
|
||||
import com.topjohnwu.magisk.Const;
|
||||
import com.topjohnwu.magisk.utils.ISafetyNetHelper;
|
||||
import com.topjohnwu.magisk.utils.Topic;
|
||||
import com.topjohnwu.net.Networking;
|
||||
import com.topjohnwu.superuser.Shell;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import dalvik.system.DexClassLoader;
|
||||
|
||||
public class SafetyNet {
|
||||
|
||||
public static final File EXT_APK =
|
||||
new File(App.self.getFilesDir().getParent() + "/snet", "snet.apk");
|
||||
|
||||
private static void dyRun(Activity activity) throws Exception {
|
||||
DexClassLoader loader = new DexClassLoader(EXT_APK.getPath(), EXT_APK.getParent(),
|
||||
null, ISafetyNetHelper.class.getClassLoader());
|
||||
Class<?> clazz = loader.loadClass("com.topjohnwu.snet.Snet");
|
||||
ISafetyNetHelper helper = (ISafetyNetHelper) clazz.getMethod("newHelper",
|
||||
Class.class, String.class, Activity.class, Object.class)
|
||||
.invoke(null, ISafetyNetHelper.class, EXT_APK.getPath(), activity,
|
||||
(ISafetyNetHelper.Callback) code ->
|
||||
Topic.publish(false, Topic.SNET_CHECK_DONE, code));
|
||||
if (helper.getVersion() < Const.SNET_EXT_VER)
|
||||
throw new Exception();
|
||||
helper.attest();
|
||||
}
|
||||
|
||||
public static void check(Activity activity) {
|
||||
try {
|
||||
dyRun(activity);
|
||||
} catch (Exception ignored) {
|
||||
Shell.sh("rm -rf " + EXT_APK.getParent()).exec();
|
||||
EXT_APK.getParentFile().mkdir();
|
||||
Networking.get(Const.Url.SNET_URL).getAsFile(EXT_APK, f -> {
|
||||
try {
|
||||
dyRun(activity);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Topic.publish(false, Topic.SNET_CHECK_DONE, -1);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
158
app/src/full/java/com/topjohnwu/magisk/components/SafetyNet.java
Normal file
158
app/src/full/java/com/topjohnwu/magisk/components/SafetyNet.java
Normal file
@ -0,0 +1,158 @@
|
||||
package com.topjohnwu.magisk.components;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.topjohnwu.magisk.App;
|
||||
import com.topjohnwu.magisk.Const;
|
||||
import com.topjohnwu.magisk.R;
|
||||
import com.topjohnwu.magisk.utils.ISafetyNetHelper;
|
||||
import com.topjohnwu.net.Networking;
|
||||
import com.topjohnwu.superuser.Shell;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.cardview.widget.CardView;
|
||||
import butterknife.BindColor;
|
||||
import butterknife.BindView;
|
||||
import butterknife.OnClick;
|
||||
import dalvik.system.DexClassLoader;
|
||||
|
||||
public class SafetyNet implements ISafetyNetHelper.Callback {
|
||||
|
||||
private static final File EXT_APK =
|
||||
new File(App.self.getFilesDir().getParent() + "/snet", "snet.apk");
|
||||
|
||||
@BindView(R.id.safetyNet_card) CardView safetyNetCard;
|
||||
@BindView(R.id.safetyNet_refresh) ImageView safetyNetRefreshIcon;
|
||||
@BindView(R.id.safetyNet_status) TextView safetyNetStatusText;
|
||||
@BindView(R.id.safetyNet_check_progress) ProgressBar safetyNetProgress;
|
||||
@BindView(R.id.safetyNet_expand) ViewGroup expandLayout;
|
||||
@BindView(R.id.cts_status_icon) ImageView ctsStatusIcon;
|
||||
@BindView(R.id.cts_status) TextView ctsStatusText;
|
||||
@BindView(R.id.basic_status_icon) ImageView basicStatusIcon;
|
||||
@BindView(R.id.basic_status) TextView basicStatusText;
|
||||
|
||||
@BindColor(R.color.red500) int colorBad;
|
||||
@BindColor(R.color.green500) int colorOK;
|
||||
|
||||
private ExpandableViewHolder expandable;
|
||||
|
||||
public SafetyNet(View v) {
|
||||
new SafetyNet_ViewBinding(this, v);
|
||||
expandable = new ExpandableViewHolder(expandLayout);
|
||||
Context context = v.getContext();
|
||||
safetyNetCard.setVisibility(hasGms(context) && Networking.checkNetworkStatus(context) ?
|
||||
View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
@OnClick(R.id.safetyNet_refresh)
|
||||
void safetyNet(View v) {
|
||||
Runnable task = () -> {
|
||||
safetyNetProgress.setVisibility(View.VISIBLE);
|
||||
safetyNetRefreshIcon.setVisibility(View.INVISIBLE);
|
||||
safetyNetStatusText.setText(R.string.checking_safetyNet_status);
|
||||
check((Activity) v.getContext());
|
||||
expandable.collapse();
|
||||
};
|
||||
if (!SafetyNet.EXT_APK.exists()) {
|
||||
// Show dialog
|
||||
new CustomAlertDialog((Activity) v.getContext())
|
||||
.setTitle(R.string.proprietary_title)
|
||||
.setMessage(R.string.proprietary_notice)
|
||||
.setCancelable(true)
|
||||
.setPositiveButton(R.string.yes, (d, i) -> task.run())
|
||||
.setNegativeButton(R.string.no_thanks, null)
|
||||
.show();
|
||||
} else {
|
||||
task.run();
|
||||
}
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
safetyNetStatusText.setText(R.string.safetyNet_check_text);
|
||||
expandable.setExpanded(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(int response) {
|
||||
safetyNetProgress.setVisibility(View.GONE);
|
||||
safetyNetRefreshIcon.setVisibility(View.VISIBLE);
|
||||
if ((response & 0x0F) == 0) {
|
||||
safetyNetStatusText.setText(R.string.safetyNet_check_success);
|
||||
|
||||
boolean b;
|
||||
b = (response & ISafetyNetHelper.CTS_PASS) != 0;
|
||||
ctsStatusText.setText("ctsProfile: " + b);
|
||||
ctsStatusIcon.setImageResource(b ? R.drawable.ic_check_circle : R.drawable.ic_cancel);
|
||||
ctsStatusIcon.setColorFilter(b ? colorOK : colorBad);
|
||||
|
||||
b = (response & ISafetyNetHelper.BASIC_PASS) != 0;
|
||||
basicStatusText.setText("basicIntegrity: " + b);
|
||||
basicStatusIcon.setImageResource(b ? R.drawable.ic_check_circle : R.drawable.ic_cancel);
|
||||
basicStatusIcon.setColorFilter(b ? colorOK : colorBad);
|
||||
|
||||
expandable.expand();
|
||||
} else {
|
||||
@StringRes int resid;
|
||||
switch (response) {
|
||||
case ISafetyNetHelper.RESPONSE_ERR:
|
||||
resid = R.string.safetyNet_res_invalid;
|
||||
break;
|
||||
case ISafetyNetHelper.CONNECTION_FAIL:
|
||||
default:
|
||||
resid = R.string.safetyNet_api_error;
|
||||
break;
|
||||
}
|
||||
safetyNetStatusText.setText(resid);
|
||||
}
|
||||
}
|
||||
|
||||
private void dyRun(Activity activity) throws Exception {
|
||||
DexClassLoader loader = new DexClassLoader(EXT_APK.getPath(), EXT_APK.getParent(),
|
||||
null, ISafetyNetHelper.class.getClassLoader());
|
||||
Class<?> clazz = loader.loadClass("com.topjohnwu.snet.Snet");
|
||||
ISafetyNetHelper helper = (ISafetyNetHelper) clazz.getMethod("newHelper",
|
||||
Class.class, String.class, Activity.class, Object.class)
|
||||
.invoke(null, ISafetyNetHelper.class, EXT_APK.getPath(), activity, this);
|
||||
if (helper.getVersion() < Const.SNET_EXT_VER)
|
||||
throw new Exception();
|
||||
helper.attest();
|
||||
}
|
||||
|
||||
private void check(Activity activity) {
|
||||
try {
|
||||
dyRun(activity);
|
||||
} catch (Exception ignored) {
|
||||
Shell.sh("rm -rf " + EXT_APK.getParent()).exec();
|
||||
EXT_APK.getParentFile().mkdir();
|
||||
Networking.get(Const.Url.SNET_URL).getAsFile(EXT_APK, f -> {
|
||||
try {
|
||||
dyRun(activity);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
onResponse(-1);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasGms(Context context) {
|
||||
PackageManager pm = context.getPackageManager();
|
||||
PackageInfo info;
|
||||
try {
|
||||
info = pm.getPackageInfo("com.google.android.gms", 0);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
return info.applicationInfo.enabled;
|
||||
}
|
||||
}
|
@ -7,10 +7,7 @@ import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.topjohnwu.magisk.BuildConfig;
|
||||
import com.topjohnwu.magisk.Config;
|
||||
@ -18,16 +15,13 @@ import com.topjohnwu.magisk.MainActivity;
|
||||
import com.topjohnwu.magisk.R;
|
||||
import com.topjohnwu.magisk.components.BaseActivity;
|
||||
import com.topjohnwu.magisk.components.BaseFragment;
|
||||
import com.topjohnwu.magisk.components.CustomAlertDialog;
|
||||
import com.topjohnwu.magisk.components.EnvFixDialog;
|
||||
import com.topjohnwu.magisk.components.ExpandableViewHolder;
|
||||
import com.topjohnwu.magisk.components.MagiskInstallDialog;
|
||||
import com.topjohnwu.magisk.components.ManagerInstallDialog;
|
||||
import com.topjohnwu.magisk.components.SafetyNet;
|
||||
import com.topjohnwu.magisk.components.UninstallDialog;
|
||||
import com.topjohnwu.magisk.components.UpdateCardHolder;
|
||||
import com.topjohnwu.magisk.tasks.CheckUpdates;
|
||||
import com.topjohnwu.magisk.tasks.SafetyNet;
|
||||
import com.topjohnwu.magisk.utils.ISafetyNetHelper;
|
||||
import com.topjohnwu.magisk.utils.Topic;
|
||||
import com.topjohnwu.net.Networking;
|
||||
import com.topjohnwu.superuser.Shell;
|
||||
@ -37,7 +31,6 @@ import java.util.Locale;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.cardview.widget.CardView;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
import androidx.transition.ChangeBounds;
|
||||
@ -57,16 +50,6 @@ public class MagiskFragment extends BaseFragment
|
||||
@BindView(R.id.swipeRefreshLayout) SwipeRefreshLayout mSwipeRefreshLayout;
|
||||
@BindView(R.id.linearLayout) LinearLayout root;
|
||||
|
||||
@BindView(R.id.safetyNet_card) CardView safetyNetCard;
|
||||
@BindView(R.id.safetyNet_refresh) ImageView safetyNetRefreshIcon;
|
||||
@BindView(R.id.safetyNet_status) TextView safetyNetStatusText;
|
||||
@BindView(R.id.safetyNet_check_progress) ProgressBar safetyNetProgress;
|
||||
@BindView(R.id.expand_layout) LinearLayout expandLayout;
|
||||
@BindView(R.id.cts_status_icon) ImageView ctsStatusIcon;
|
||||
@BindView(R.id.cts_status) TextView ctsStatusText;
|
||||
@BindView(R.id.basic_status_icon) ImageView basicStatusIcon;
|
||||
@BindView(R.id.basic_status) TextView basicStatusText;
|
||||
|
||||
@BindView(R.id.install_option_card) CardView installOptionCard;
|
||||
@BindView(R.id.keep_force_enc) CheckBox keepEncChkbox;
|
||||
@BindView(R.id.keep_verity) CheckBox keepVerityChkbox;
|
||||
@ -80,32 +63,9 @@ public class MagiskFragment extends BaseFragment
|
||||
|
||||
private UpdateCardHolder magisk;
|
||||
private UpdateCardHolder manager;
|
||||
private ExpandableViewHolder snExpandableHolder;
|
||||
private SafetyNet safetyNet;
|
||||
private Transition transition;
|
||||
|
||||
@OnClick(R.id.safetyNet_title)
|
||||
void safetyNet() {
|
||||
Runnable task = () -> {
|
||||
safetyNetProgress.setVisibility(View.VISIBLE);
|
||||
safetyNetRefreshIcon.setVisibility(View.GONE);
|
||||
safetyNetStatusText.setText(R.string.checking_safetyNet_status);
|
||||
SafetyNet.check(requireActivity());
|
||||
snExpandableHolder.collapse();
|
||||
};
|
||||
if (!SafetyNet.EXT_APK.exists()) {
|
||||
// Show dialog
|
||||
new CustomAlertDialog(requireActivity())
|
||||
.setTitle(R.string.proprietary_title)
|
||||
.setMessage(R.string.proprietary_notice)
|
||||
.setCancelable(true)
|
||||
.setPositiveButton(R.string.yes, (d, i) -> task.run())
|
||||
.setNegativeButton(R.string.no_thanks, null)
|
||||
.show();
|
||||
} else {
|
||||
task.run();
|
||||
}
|
||||
}
|
||||
|
||||
private void magiskInstall(View v) {
|
||||
// Show Manager update first
|
||||
if (Config.remoteManagerVersionCode > BuildConfig.VERSION_CODE) {
|
||||
@ -132,8 +92,7 @@ public class MagiskFragment extends BaseFragment
|
||||
unbinder = new MagiskFragment_ViewBinding(this, v);
|
||||
requireActivity().setTitle(R.string.magisk);
|
||||
|
||||
snExpandableHolder = new ExpandableViewHolder(expandLayout);
|
||||
|
||||
safetyNet = new SafetyNet(v);
|
||||
magisk = new UpdateCardHolder(inflater, root);
|
||||
manager = new UpdateCardHolder(inflater, root);
|
||||
root.addView(magisk.itemView, 0);
|
||||
@ -157,9 +116,6 @@ public class MagiskFragment extends BaseFragment
|
||||
manager.additional.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
safetyNetCard.setVisibility(hasGms() && Networking.checkNetworkStatus(app) ?
|
||||
View.VISIBLE : View.GONE);
|
||||
|
||||
transition = new TransitionSet()
|
||||
.setOrdering(TransitionSet.ORDERING_TOGETHER)
|
||||
.addTransition(new Fade(Fade.OUT))
|
||||
@ -172,11 +128,9 @@ public class MagiskFragment extends BaseFragment
|
||||
|
||||
@Override
|
||||
public void onRefresh() {
|
||||
safetyNetStatusText.setText(R.string.safetyNet_check_text);
|
||||
snExpandableHolder.setExpanded(false);
|
||||
|
||||
mSwipeRefreshLayout.setRefreshing(false);
|
||||
TransitionManager.beginDelayedTransition(root, transition);
|
||||
safetyNet.reset();
|
||||
magisk.reset();
|
||||
manager.reset();
|
||||
|
||||
@ -197,19 +151,12 @@ public class MagiskFragment extends BaseFragment
|
||||
|
||||
@Override
|
||||
public int[] getSubscribedTopics() {
|
||||
return new int[] {Topic.SNET_CHECK_DONE, Topic.UPDATE_CHECK_DONE};
|
||||
return new int[] {Topic.UPDATE_CHECK_DONE};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPublish(int topic, Object[] result) {
|
||||
switch (topic) {
|
||||
case Topic.SNET_CHECK_DONE:
|
||||
updateSafetyNetUI((int) result[0]);
|
||||
break;
|
||||
case Topic.UPDATE_CHECK_DONE:
|
||||
updateCheckUI();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasGms() {
|
||||
@ -334,38 +281,5 @@ public class MagiskFragment extends BaseFragment
|
||||
new EnvFixDialog(requireActivity()).show();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateSafetyNetUI(int response) {
|
||||
safetyNetProgress.setVisibility(View.GONE);
|
||||
safetyNetRefreshIcon.setVisibility(View.VISIBLE);
|
||||
if ((response & 0x0F) == 0) {
|
||||
safetyNetStatusText.setText(R.string.safetyNet_check_success);
|
||||
|
||||
boolean b;
|
||||
b = (response & ISafetyNetHelper.CTS_PASS) != 0;
|
||||
ctsStatusText.setText("ctsProfile: " + b);
|
||||
ctsStatusIcon.setImageResource(b ? R.drawable.ic_check_circle : R.drawable.ic_cancel);
|
||||
ctsStatusIcon.setColorFilter(b ? colorOK : colorBad);
|
||||
|
||||
b = (response & ISafetyNetHelper.BASIC_PASS) != 0;
|
||||
basicStatusText.setText("basicIntegrity: " + b);
|
||||
basicStatusIcon.setImageResource(b ? R.drawable.ic_check_circle : R.drawable.ic_cancel);
|
||||
basicStatusIcon.setColorFilter(b ? colorOK : colorBad);
|
||||
|
||||
snExpandableHolder.expand();
|
||||
} else {
|
||||
@StringRes int resid;
|
||||
switch (response) {
|
||||
case ISafetyNetHelper.RESPONSE_ERR:
|
||||
resid = R.string.safetyNet_res_invalid;
|
||||
break;
|
||||
case ISafetyNetHelper.CONNECTION_FAIL:
|
||||
default:
|
||||
resid = R.string.safetyNet_api_error;
|
||||
break;
|
||||
}
|
||||
safetyNetStatusText.setText(resid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,5 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#fff"
|
||||
android:pathData="M10,16h4c0.55,0 1,-0.45 1,-1v-3c0,-0.55 -0.45,-1 -1,-1v-1c0,-1.11 -0.9,-2 -2,-2 -1.11,0 -2,0.9 -2,2v1c-0.55,0 -1,0.45 -1,1v3c0,0.55 0.45,1 1,1zM10.8,10c0,-0.66 0.54,-1.2 1.2,-1.2 0.66,0 1.2,0.54 1.2,1.2v1h-2.4v-1zM17,1L7,1c-1.1,0 -2,0.9 -2,2v18c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2L19,3c0,-1.1 -0.9,-2 -2,-2zM17,19L7,19L7,5h10v14z"/>
|
||||
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FF000000" android:pathData="M12,1L3,5v6c0,5.55 3.84,10.74 9,12 5.16,-1.26 9,-6.45 9,-12L21,5l-9,-4zM12,11.99h7c-0.53,4.12 -3.28,7.79 -7,8.94L12,12L5,12L5,6.3l7,-3.11v8.8z"/>
|
||||
</vector>
|
||||
|
@ -36,101 +36,105 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/safetyNet_title"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/safetyNet_refresh"
|
||||
android:layout_width="25dp"
|
||||
android:layout_height="25dp"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_margin="15dp"
|
||||
android:layout_toStartOf="@+id/safetyNet_status"
|
||||
app:srcCompat="@drawable/ic_refresh" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/safetyNet_check_progress"
|
||||
android:layout_width="25dp"
|
||||
android:layout_height="25dp"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_margin="15dp"
|
||||
android:layout_toStartOf="@+id/safetyNet_status"
|
||||
android:visibility="gone" />
|
||||
android:id="@+id/sn_logo"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginEnd="24dp"
|
||||
android:layout_marginBottom="12dp"
|
||||
android:tint="@color/green500"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/safetyNet_status"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:srcCompat="@drawable/ic_safetynet" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/safetyNet_status"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:gravity="center"
|
||||
android:minWidth="175dp"
|
||||
android:padding="6dp"
|
||||
android:minWidth="200dp"
|
||||
android:text="@string/safetyNet_check_text"
|
||||
android:textStyle="bold" />
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</RelativeLayout>
|
||||
<ImageView
|
||||
android:id="@+id/safetyNet_refresh"
|
||||
android:layout_width="25dp"
|
||||
android:layout_height="25dp"
|
||||
android:layout_marginStart="24dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/safetyNet_status"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:srcCompat="@drawable/ic_refresh" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/expand_layout"
|
||||
<ProgressBar
|
||||
android:id="@+id/safetyNet_check_progress"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/safetyNet_refresh"
|
||||
app:layout_constraintEnd_toEndOf="@+id/safetyNet_refresh"
|
||||
app:layout_constraintStart_toStartOf="@+id/safetyNet_refresh"
|
||||
app:layout_constraintTop_toTopOf="@+id/safetyNet_refresh" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/safetyNet_expand"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingStart="10dp"
|
||||
android:paddingEnd="10dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal">
|
||||
android:paddingBottom="10dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/cts_status_icon"
|
||||
android:layout_width="25dp"
|
||||
android:layout_height="25dp"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:layout_marginBottom="5dp" />
|
||||
android:layout_marginEnd="8dp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/cts_status"
|
||||
app:layout_constraintEnd_toStartOf="@+id/cts_status"
|
||||
app:layout_constraintTop_toTopOf="@+id/cts_status" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/cts_status"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:minWidth="150dp"
|
||||
android:padding="6dp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal">
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintEnd_toEndOf="@+id/basic_status"
|
||||
app:layout_constraintStart_toStartOf="@+id/basic_status"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/basic_status_icon"
|
||||
android:layout_width="25dp"
|
||||
android:layout_height="25dp"
|
||||
android:layout_margin="10dp" />
|
||||
android:layout_marginEnd="8dp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/basic_status"
|
||||
app:layout_constraintEnd_toStartOf="@+id/basic_status"
|
||||
app:layout_constraintTop_toTopOf="@+id/basic_status" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/basic_status"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:minWidth="150dp"
|
||||
android:padding="6dp"
|
||||
android:textStyle="bold" />
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/cts_status" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
<string name="checking_for_updates">Checking for updates…</string>
|
||||
<string name="magisk_update_available">Magisk v%1$s is available!</string>
|
||||
<string name="invalid_update_channel">Invalid Update Channel</string>
|
||||
<string name="safetyNet_check_text">Tap to start SafetyNet check.</string>
|
||||
<string name="safetyNet_check_text">Tap to start SafetyNet check</string>
|
||||
<string name="checking_safetyNet_status">Checking SafetyNet status…</string>
|
||||
<string name="safetyNet_check_success">SafetyNet Check Success</string>
|
||||
<string name="safetyNet_api_error">SafetyNet API Error</string>
|
||||
|
Loading…
Reference in New Issue
Block a user