Restructure SuRequestActivity

This commit is contained in:
topjohnwu 2019-04-10 17:02:32 -04:00
parent 0165602515
commit fbdd72273e

View File

@ -1,5 +1,6 @@
package com.topjohnwu.magisk; package com.topjohnwu.magisk;
import android.annotation.SuppressLint;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
@ -25,8 +26,11 @@ import com.topjohnwu.magisk.utils.FingerprintHelper;
import com.topjohnwu.magisk.utils.SuConnector; import com.topjohnwu.magisk.utils.SuConnector;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import butterknife.BindView; import butterknife.BindView;
import java9.lang.Iterables;
public class SuRequestActivity extends BaseActivity { public class SuRequestActivity extends BaseActivity {
@BindView(R.id.su_popup) LinearLayout suPopup; @BindView(R.id.su_popup) LinearLayout suPopup;
@ -39,10 +43,8 @@ public class SuRequestActivity extends BaseActivity {
@BindView(R.id.fingerprint) ImageView fingerprintImg; @BindView(R.id.fingerprint) ImageView fingerprintImg;
@BindView(R.id.warning) TextView warning; @BindView(R.id.warning) TextView warning;
private SuConnector connector; private ActionHandler handler;
private Policy policy; private Policy policy;
private CountDownTimer timer;
private FingerprintHelper fingerprintHelper;
private SharedPreferences timeoutPrefs; private SharedPreferences timeoutPrefs;
@Override @Override
@ -50,22 +52,9 @@ public class SuRequestActivity extends BaseActivity {
return R.style.SuRequest_Dark; return R.style.SuRequest_Dark;
} }
@Override
public void finish() {
if (timer != null)
timer.cancel();
if (fingerprintHelper != null)
fingerprintHelper.cancel();
super.finish();
}
@Override @Override
public void onBackPressed() { public void onBackPressed() {
if (policy != null) { handler.handleAction(Policy.DENY, -1);
handleAction(Policy.DENY);
} else {
finish();
}
} }
@Override @Override
@ -74,14 +63,15 @@ public class SuRequestActivity extends BaseActivity {
lockOrientation(); lockOrientation();
supportRequestWindowFeature(Window.FEATURE_NO_TITLE); supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
PackageManager pm = getPackageManager();
app.mDB.clearOutdated(); app.mDB.clearOutdated();
timeoutPrefs = App.deContext.getSharedPreferences("su_timeout", 0); timeoutPrefs = App.deContext.getSharedPreferences("su_timeout", 0);
// Get policy // Get policy
Intent intent = getIntent(); Intent intent = getIntent();
try {
String socketName = intent.getStringExtra("socket"); String socketName = intent.getStringExtra("socket");
if (socketName != null) {
SuConnector connector;
try {
connector = new SuConnector(socketName) { connector = new SuConnector(socketName) {
@Override @Override
protected void onResponse() throws IOException { protected void onResponse() throws IOException {
@ -92,13 +82,42 @@ public class SuRequestActivity extends BaseActivity {
int uid = Integer.parseInt(bundle.getString("uid")); int uid = Integer.parseInt(bundle.getString("uid"));
policy = app.mDB.getPolicy(uid); policy = app.mDB.getPolicy(uid);
if (policy == null) { if (policy == null) {
policy = new Policy(uid, pm); policy = new Policy(uid, getPackageManager());
} }
} catch (IOException | PackageManager.NameNotFoundException e) { } catch (IOException | PackageManager.NameNotFoundException e) {
e.printStackTrace(); e.printStackTrace();
finish(); finish();
return; return;
} }
handler = new ActionHandler() {
@Override
void handleAction() {
connector.response();
done();
}
@Override
void handleAction(int action) {
int pos = timeout.getSelectedItemPosition();
timeoutPrefs.edit().putInt(policy.packageName, pos).apply();
handleAction(action, Config.Value.TIMEOUT_LIST[pos]);
}
@Override
void handleAction(int action, int time) {
policy.policy = action;
if (time >= 0) {
policy.until = (time == 0) ? 0
: (System.currentTimeMillis() / 1000 + time * 60);
app.mDB.updatePolicy(policy);
}
handleAction();
}
};
} else {
finish();
return;
}
// Never allow com.topjohnwu.magisk (could be malware) // Never allow com.topjohnwu.magisk (could be malware)
if (TextUtils.equals(policy.packageName, BuildConfig.APPLICATION_ID)) { if (TextUtils.equals(policy.packageName, BuildConfig.APPLICATION_ID)) {
@ -106,27 +125,30 @@ public class SuRequestActivity extends BaseActivity {
return; return;
} }
switch ((int) Config.get(Config.Key.SU_AUTO_RESPONSE)) {
case Config.Value.SU_AUTO_DENY:
handleAction(Policy.DENY, 0);
return;
case Config.Value.SU_AUTO_ALLOW:
handleAction(Policy.ALLOW, 0);
return;
case Config.Value.SU_PROMPT:
default:
}
// If not interactive, response directly // If not interactive, response directly
if (policy.policy != Policy.INTERACTIVE) { if (policy.policy != Policy.INTERACTIVE) {
handleAction(); handler.handleAction();
return; return;
} }
switch ((int) Config.get(Config.Key.SU_AUTO_RESPONSE)) {
case Config.Value.SU_AUTO_DENY:
handler.handleAction(Policy.DENY, 0);
return;
case Config.Value.SU_AUTO_ALLOW:
handler.handleAction(Policy.ALLOW, 0);
return;
}
showUI();
}
@SuppressLint("ClickableViewAccessibility")
private void showUI() {
setContentView(R.layout.activity_request); setContentView(R.layout.activity_request);
new SuRequestActivity_ViewBinding(this); new SuRequestActivity_ViewBinding(this);
appIcon.setImageDrawable(policy.info.loadIcon(pm)); appIcon.setImageDrawable(policy.info.loadIcon(getPackageManager()));
appNameView.setText(policy.appName); appNameView.setText(policy.appName);
packageNameView.setText(policy.packageName); packageNameView.setText(policy.packageName);
warning.setCompoundDrawablesRelativeWithIntrinsicBounds( warning.setCompoundDrawablesRelativeWithIntrinsicBounds(
@ -138,23 +160,62 @@ public class SuRequestActivity extends BaseActivity {
timeout.setAdapter(adapter); timeout.setAdapter(adapter);
timeout.setSelection(timeoutPrefs.getInt(policy.packageName, 0)); timeout.setSelection(timeoutPrefs.getInt(policy.packageName, 0));
timer = new CountDownTimer((int) Config.get(Config.Key.SU_REQUEST_TIMEOUT) * 1000, 1000) { CountDownTimer timer = new CountDownTimer(
(int) Config.get(Config.Key.SU_REQUEST_TIMEOUT) * 1000, 1000) {
@Override @Override
public void onTick(long millisUntilFinished) { public void onTick(long remains) {
deny_btn.setText(getString(R.string.deny_with_str, "(" + millisUntilFinished / 1000 + ")")); deny_btn.setText(getString(R.string.deny) + "(" + remains / 1000 + ")");
} }
@Override @Override
public void onFinish() { public void onFinish() {
deny_btn.setText(getString(R.string.deny_with_str, "(0)")); deny_btn.setText(getString(R.string.deny));
handleAction(Policy.DENY); handler.handleAction(Policy.DENY);
} }
}; };
timer.start();
Runnable cancelTimer = () -> {
timer.cancel();
deny_btn.setText(getString(R.string.deny));
};
handler.addCancel(cancelTimer);
boolean useFP = FingerprintHelper.useFingerprint(); boolean useFP = FingerprintHelper.useFingerprint();
if (useFP) { if (useFP) try {
try { FingerprintHelper helper = new SuFingerprint();
fingerprintHelper = new FingerprintHelper() { helper.authenticate();
handler.addCancel(helper::cancel);
} catch (Exception e) {
e.printStackTrace();
useFP = false;
}
if (!useFP) {
grant_btn.setOnClickListener(v -> {
handler.handleAction(Policy.ALLOW);
timer.cancel();
});
grant_btn.requestFocus();
}
grant_btn.setVisibility(useFP ? View.GONE : View.VISIBLE);
fingerprintImg.setVisibility(useFP ? View.VISIBLE : View.GONE);
deny_btn.setOnClickListener(v -> {
handler.handleAction(Policy.DENY);
timer.cancel();
});
suPopup.setOnClickListener(v -> cancelTimer.run());
timeout.setOnTouchListener((v, event) -> {
cancelTimer.run();
return false;
});
}
private class SuFingerprint extends FingerprintHelper {
SuFingerprint() throws Exception {}
@Override @Override
public void onAuthenticationError(int errorCode, CharSequence errString) { public void onAuthenticationError(int errorCode, CharSequence errString) {
warning.setText(errString); warning.setText(errString);
@ -167,64 +228,37 @@ public class SuRequestActivity extends BaseActivity {
@Override @Override
public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) { public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
handleAction(Policy.ALLOW); handler.handleAction(Policy.ALLOW);
} }
@Override @Override
public void onAuthenticationFailed() { public void onAuthenticationFailed() {
warning.setText(R.string.auth_fail); warning.setText(R.string.auth_fail);
} }
};
fingerprintHelper.authenticate();
} catch (Exception e) {
e.printStackTrace();
useFP = false;
}
} }
if (!useFP) { private class ActionHandler {
grant_btn.setOnClickListener(v -> { private List<Runnable> cancelTasks = new ArrayList<>();
handleAction(Policy.ALLOW);
timer.cancel(); void handleAction() {
}); done();
grant_btn.requestFocus();
} }
grant_btn.setVisibility(useFP ? View.GONE : View.VISIBLE); void handleAction(int action) {
fingerprintImg.setVisibility(useFP ? View.VISIBLE : View.GONE); done();
deny_btn.setOnClickListener(v -> {
handleAction(Policy.DENY);
timer.cancel();
});
suPopup.setOnClickListener(v -> cancelTimeout());
timeout.setOnTouchListener((v, event) -> cancelTimeout());
timer.start();
} }
private boolean cancelTimeout() { void handleAction(int action, int time) {
timer.cancel(); done();
deny_btn.setText(getString(R.string.deny));
return false;
} }
private void handleAction() { void addCancel(Runnable r) {
connector.response(); cancelTasks.add(r);
}
void done() {
Iterables.forEach(cancelTasks, Runnable::run);
finish(); finish();
} }
private void handleAction(int action) {
int pos = timeout.getSelectedItemPosition();
timeoutPrefs.edit().putInt(policy.packageName, pos).apply();
handleAction(action, Config.Value.TIMEOUT_LIST[pos]);
}
private void handleAction(int action, int time) {
policy.policy = action;
if (time >= 0) {
policy.until = (time == 0) ? 0 : (System.currentTimeMillis() / 1000 + time * 60);
app.mDB.updatePolicy(policy);
}
handleAction();
} }
} }