mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-27 20:15:29 +00:00
Do not place files into /sdcard/MagiskManager
This commit is contained in:
parent
3948e67c8f
commit
9bbfcf326c
@ -1,9 +1,9 @@
|
|||||||
package com.topjohnwu.magisk;
|
package com.topjohnwu.magisk;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
|
||||||
import android.support.v7.app.ActionBar;
|
import android.support.v7.app.ActionBar;
|
||||||
import android.support.v7.widget.Toolbar;
|
import android.support.v7.widget.Toolbar;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
@ -57,15 +57,15 @@ public class FlashActivity extends BaseActivity {
|
|||||||
|
|
||||||
@OnClick(R.id.save_logs)
|
@OnClick(R.id.save_logs)
|
||||||
void saveLogs() {
|
void saveLogs() {
|
||||||
|
runWithPermission(new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE}, () -> {
|
||||||
Calendar now = Calendar.getInstance();
|
Calendar now = Calendar.getInstance();
|
||||||
String filename = String.format(Locale.US,
|
String filename = String.format(Locale.US,
|
||||||
"install_log_%04d%02d%02d_%02d%02d%02d.log",
|
"magisk_install_log_%04d%02d%02d_%02d%02d%02d.log",
|
||||||
now.get(Calendar.YEAR), now.get(Calendar.MONTH) + 1,
|
now.get(Calendar.YEAR), now.get(Calendar.MONTH) + 1,
|
||||||
now.get(Calendar.DAY_OF_MONTH), now.get(Calendar.HOUR_OF_DAY),
|
now.get(Calendar.DAY_OF_MONTH), now.get(Calendar.HOUR_OF_DAY),
|
||||||
now.get(Calendar.MINUTE), now.get(Calendar.SECOND));
|
now.get(Calendar.MINUTE), now.get(Calendar.SECOND));
|
||||||
|
|
||||||
File logFile = new File(Download.EXTERNAL_PATH + "/logs", filename);
|
File logFile = new File(Download.EXTERNAL_PATH, filename);
|
||||||
logFile.getParentFile().mkdirs();
|
|
||||||
try (FileWriter writer = new FileWriter(logFile)) {
|
try (FileWriter writer = new FileWriter(logFile)) {
|
||||||
for (String s : logs) {
|
for (String s : logs) {
|
||||||
writer.write(s);
|
writer.write(s);
|
||||||
@ -76,6 +76,7 @@ public class FlashActivity extends BaseActivity {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Utils.toast(logFile.getPath(), Toast.LENGTH_LONG);
|
Utils.toast(logFile.getPath(), Toast.LENGTH_LONG);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -158,7 +159,7 @@ public class FlashActivity extends BaseActivity {
|
|||||||
@Override
|
@Override
|
||||||
protected void onPostExecute(Integer result) {
|
protected void onPostExecute(Integer result) {
|
||||||
if (result == 1) {
|
if (result == 1) {
|
||||||
new Handler().postDelayed(() ->
|
Data.mainHandler.postDelayed(() ->
|
||||||
RootUtils.uninstallPkg(getActivity().getPackageName()), 3000);
|
RootUtils.uninstallPkg(getActivity().getPackageName()), 3000);
|
||||||
} else {
|
} else {
|
||||||
super.onPostExecute(result);
|
super.onPostExecute(result);
|
||||||
|
@ -108,16 +108,15 @@ public class MagiskLogFragment extends BaseFragment {
|
|||||||
now.get(Calendar.DAY_OF_MONTH), now.get(Calendar.HOUR_OF_DAY),
|
now.get(Calendar.DAY_OF_MONTH), now.get(Calendar.HOUR_OF_DAY),
|
||||||
now.get(Calendar.MINUTE), now.get(Calendar.SECOND));
|
now.get(Calendar.MINUTE), now.get(Calendar.SECOND));
|
||||||
|
|
||||||
File targetFile = new File(Download.EXTERNAL_PATH + "/logs", filename);
|
File logFile = new File(Download.EXTERNAL_PATH, filename);
|
||||||
targetFile.getParentFile().mkdirs();
|
|
||||||
try {
|
try {
|
||||||
targetFile.createNewFile();
|
logFile.createNewFile();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Shell.su("cat " + Const.MAGISK_LOG + " > " + targetFile)
|
Shell.su("cat " + Const.MAGISK_LOG + " > " + logFile)
|
||||||
.submit(result ->
|
.submit(result ->
|
||||||
SnackbarMaker.make(txtLog, targetFile.getPath(), Snackbar.LENGTH_SHORT).show());
|
SnackbarMaker.make(txtLog, logFile.getPath(), Snackbar.LENGTH_SHORT).show());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearLogs() {
|
public void clearLogs() {
|
||||||
|
@ -100,16 +100,15 @@ public class ReposAdapter extends SectionedAdapter<ReposAdapter.SectionHolder, R
|
|||||||
new MarkDownWindow((BaseActivity) context, null, repo.getDetailUrl()).exec());
|
new MarkDownWindow((BaseActivity) context, null, repo.getDetailUrl()).exec());
|
||||||
|
|
||||||
holder.downloadImage.setOnClickListener(v -> {
|
holder.downloadImage.setOnClickListener(v -> {
|
||||||
String filename = repo.getName() + "-" + repo.getVersion() + ".zip";
|
|
||||||
new CustomAlertDialog((BaseActivity) context)
|
new CustomAlertDialog((BaseActivity) context)
|
||||||
.setTitle(context.getString(R.string.repo_install_title, repo.getName()))
|
.setTitle(context.getString(R.string.repo_install_title, repo.getName()))
|
||||||
.setMessage(context.getString(R.string.repo_install_msg, filename))
|
.setMessage(context.getString(R.string.repo_install_msg, repo.getDownloadFilename()))
|
||||||
.setCancelable(true)
|
.setCancelable(true)
|
||||||
.setPositiveButton(R.string.install, (d, i) ->
|
.setPositiveButton(R.string.install, (d, i) ->
|
||||||
new ProcessRepoZip((BaseActivity) context, repo.getZipUrl(), filename, true).exec()
|
new ProcessRepoZip((BaseActivity) context, repo, true).exec()
|
||||||
)
|
)
|
||||||
.setNeutralButton(R.string.download, (d, i) ->
|
.setNeutralButton(R.string.download, (d, i) ->
|
||||||
new ProcessRepoZip((BaseActivity) context, repo.getZipUrl(), filename, false).exec())
|
new ProcessRepoZip((BaseActivity) context, repo, false).exec())
|
||||||
.setNegativeButton(R.string.no_thanks, null)
|
.setNegativeButton(R.string.no_thanks, null)
|
||||||
.show();
|
.show();
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package com.topjohnwu.magisk.asyncs;
|
package com.topjohnwu.magisk.asyncs;
|
||||||
|
|
||||||
import android.Manifest;
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.ProgressDialog;
|
import android.app.ProgressDialog;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
@ -15,7 +14,6 @@ import com.topjohnwu.magisk.Data;
|
|||||||
import com.topjohnwu.magisk.FlashActivity;
|
import com.topjohnwu.magisk.FlashActivity;
|
||||||
import com.topjohnwu.magisk.MagiskManager;
|
import com.topjohnwu.magisk.MagiskManager;
|
||||||
import com.topjohnwu.magisk.R;
|
import com.topjohnwu.magisk.R;
|
||||||
import com.topjohnwu.magisk.components.BaseActivity;
|
|
||||||
import com.topjohnwu.magisk.container.TarEntry;
|
import com.topjohnwu.magisk.container.TarEntry;
|
||||||
import com.topjohnwu.magisk.utils.Download;
|
import com.topjohnwu.magisk.utils.Download;
|
||||||
import com.topjohnwu.magisk.utils.Utils;
|
import com.topjohnwu.magisk.utils.Utils;
|
||||||
@ -79,11 +77,6 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
|||||||
bootUri = boot;
|
bootUri = boot;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected BaseActivity getActivity() {
|
|
||||||
return (BaseActivity) super.getActivity();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPreExecute() {
|
protected void onPreExecute() {
|
||||||
if (mode == FIX_ENV_MODE) {
|
if (mode == FIX_ENV_MODE) {
|
||||||
@ -137,10 +130,7 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void extractFiles(String arch) throws IOException {
|
private void extractFiles(String arch) throws IOException {
|
||||||
String filename = Utils.fmt("Magisk-v%s(%d).zip",
|
File zip = new File(mm.getFilesDir(), "magisk.zip");
|
||||||
Data.remoteMagiskVersionString, Data.remoteMagiskVersionCode);
|
|
||||||
File zip = new File(Download.EXTERNAL_PATH, filename);
|
|
||||||
zip.getParentFile().mkdirs();
|
|
||||||
BufferedInputStream buf;
|
BufferedInputStream buf;
|
||||||
|
|
||||||
if (!ShellUtils.checkSum("MD5", zip, Data.magiskMD5)) {
|
if (!ShellUtils.checkSum("MD5", zip, Data.magiskMD5)) {
|
||||||
@ -404,10 +394,4 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
|||||||
activity.buttonPanel.setVisibility(View.VISIBLE);
|
activity.buttonPanel.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void exec(Void... voids) {
|
|
||||||
getActivity().runWithPermission(
|
|
||||||
new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE}, super::exec);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -4,15 +4,16 @@ import android.Manifest;
|
|||||||
import android.app.ProgressDialog;
|
import android.app.ProgressDialog;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Handler;
|
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.topjohnwu.magisk.Const;
|
import com.topjohnwu.magisk.Const;
|
||||||
|
import com.topjohnwu.magisk.Data;
|
||||||
import com.topjohnwu.magisk.FlashActivity;
|
import com.topjohnwu.magisk.FlashActivity;
|
||||||
import com.topjohnwu.magisk.R;
|
import com.topjohnwu.magisk.R;
|
||||||
import com.topjohnwu.magisk.components.BaseActivity;
|
import com.topjohnwu.magisk.components.BaseActivity;
|
||||||
import com.topjohnwu.magisk.components.SnackbarMaker;
|
import com.topjohnwu.magisk.components.SnackbarMaker;
|
||||||
|
import com.topjohnwu.magisk.container.Repo;
|
||||||
import com.topjohnwu.magisk.utils.Download;
|
import com.topjohnwu.magisk.utils.Download;
|
||||||
import com.topjohnwu.magisk.utils.Utils;
|
import com.topjohnwu.magisk.utils.Utils;
|
||||||
import com.topjohnwu.magisk.utils.WebService;
|
import com.topjohnwu.magisk.utils.WebService;
|
||||||
@ -38,17 +39,15 @@ public class ProcessRepoZip extends ParallelTask<Void, Object, Boolean> {
|
|||||||
|
|
||||||
private ProgressDialog progressDialog;
|
private ProgressDialog progressDialog;
|
||||||
private boolean mInstall;
|
private boolean mInstall;
|
||||||
private String mLink;
|
|
||||||
private File mFile;
|
private File mFile;
|
||||||
|
private Repo mRepo;
|
||||||
private int progress = 0, total = -1;
|
private int progress = 0, total = -1;
|
||||||
private Handler mHandler;
|
|
||||||
|
|
||||||
public ProcessRepoZip(BaseActivity context, String link, String filename, boolean install) {
|
public ProcessRepoZip(BaseActivity context, Repo repo, boolean install) {
|
||||||
super(context);
|
super(context);
|
||||||
mLink = link;
|
mRepo = repo;
|
||||||
mFile = new File(Download.EXTERNAL_PATH, Download.getLegalFilename(filename));
|
mInstall = install && Shell.rootAccess();
|
||||||
mInstall = install;
|
mFile = new File(Download.EXTERNAL_PATH, repo.getDownloadFilename());
|
||||||
mHandler = new Handler();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeTopFolder(File input, File output) throws IOException {
|
private void removeTopFolder(File input, File output) throws IOException {
|
||||||
@ -93,7 +92,7 @@ public class ProcessRepoZip extends ParallelTask<Void, Object, Boolean> {
|
|||||||
if (activity == null) return null;
|
if (activity == null) return null;
|
||||||
try {
|
try {
|
||||||
// Request zip from Internet
|
// Request zip from Internet
|
||||||
HttpURLConnection conn = WebService.mustRequest(mLink, null);
|
HttpURLConnection conn = WebService.mustRequest(mRepo.getZipUrl(), null);
|
||||||
total = conn.getContentLength();
|
total = conn.getContentLength();
|
||||||
|
|
||||||
// Temp files
|
// Temp files
|
||||||
@ -111,7 +110,7 @@ public class ProcessRepoZip extends ParallelTask<Void, Object, Boolean> {
|
|||||||
}
|
}
|
||||||
conn.disconnect();
|
conn.disconnect();
|
||||||
|
|
||||||
mHandler.post(() -> {
|
Data.mainHandler.post(() -> {
|
||||||
progressDialog.setTitle(R.string.zip_process_title);
|
progressDialog.setTitle(R.string.zip_process_title);
|
||||||
progressDialog.setMessage(getActivity().getString(R.string.zip_process_msg));
|
progressDialog.setMessage(getActivity().getString(R.string.zip_process_msg));
|
||||||
});
|
});
|
||||||
@ -140,7 +139,7 @@ public class ProcessRepoZip extends ParallelTask<Void, Object, Boolean> {
|
|||||||
progressDialog.dismiss();
|
progressDialog.dismiss();
|
||||||
if (result) {
|
if (result) {
|
||||||
Uri uri = Uri.fromFile(mFile);
|
Uri uri = Uri.fromFile(mFile);
|
||||||
if (Shell.rootAccess() && mInstall) {
|
if (mInstall) {
|
||||||
Intent intent = new Intent(activity, FlashActivity.class);
|
Intent intent = new Intent(activity, FlashActivity.class);
|
||||||
intent.setData(uri).putExtra(Const.Key.FLASH_ACTION, Const.Value.FLASH_ZIP);
|
intent.setData(uri).putExtra(Const.Key.FLASH_ACTION, Const.Value.FLASH_ZIP);
|
||||||
activity.startActivity(intent);
|
activity.startActivity(intent);
|
||||||
@ -175,7 +174,7 @@ public class ProcessRepoZip extends ParallelTask<Void, Object, Boolean> {
|
|||||||
public synchronized int read() throws IOException {
|
public synchronized int read() throws IOException {
|
||||||
int b = super.read();
|
int b = super.read();
|
||||||
if (b > 0) {
|
if (b > 0) {
|
||||||
mHandler.post(() -> updateDlProgress(1));
|
Data.mainHandler.post(() -> updateDlProgress(1));
|
||||||
}
|
}
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
@ -189,7 +188,7 @@ public class ProcessRepoZip extends ParallelTask<Void, Object, Boolean> {
|
|||||||
public synchronized int read(@NonNull byte[] b, int off, int len) throws IOException {
|
public synchronized int read(@NonNull byte[] b, int off, int len) throws IOException {
|
||||||
int read = super.read(b, off, len);
|
int read = super.read(b, off, len);
|
||||||
if (read > 0) {
|
if (read > 0) {
|
||||||
mHandler.post(() -> updateDlProgress(read));
|
Data.mainHandler.post(() -> updateDlProgress(read));
|
||||||
}
|
}
|
||||||
return read;
|
return read;
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ import java.util.List;
|
|||||||
|
|
||||||
class InstallMethodDialog extends AlertDialog.Builder {
|
class InstallMethodDialog extends AlertDialog.Builder {
|
||||||
|
|
||||||
InstallMethodDialog(BaseActivity activity, List<String> options, String filename) {
|
InstallMethodDialog(BaseActivity activity, List<String> options) {
|
||||||
super(activity);
|
super(activity);
|
||||||
setTitle(R.string.select_method);
|
setTitle(R.string.select_method);
|
||||||
setItems(options.toArray(new String [0]), (dialog, idx) -> {
|
setItems(options.toArray(new String [0]), (dialog, idx) -> {
|
||||||
@ -45,6 +45,8 @@ class InstallMethodDialog extends AlertDialog.Builder {
|
|||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case 0:
|
case 0:
|
||||||
|
String filename = Utils.fmt("Magisk-v%s(%d).zip",
|
||||||
|
Data.remoteMagiskVersionString, Data.remoteMagiskVersionCode);
|
||||||
Download.receive(activity, new DownloadReceiver() {
|
Download.receive(activity, new DownloadReceiver() {
|
||||||
@Override
|
@Override
|
||||||
public void onDownloadDone(Context context, Uri uri) {
|
public void onDownloadDone(Context context, Uri uri) {
|
||||||
|
@ -34,7 +34,7 @@ public class MagiskInstallDialog extends CustomAlertDialog {
|
|||||||
if (!s.isEmpty() && Boolean.parseBoolean(s)) {
|
if (!s.isEmpty() && Boolean.parseBoolean(s)) {
|
||||||
options.add(mm.getString(R.string.install_inactive_slot));
|
options.add(mm.getString(R.string.install_inactive_slot));
|
||||||
}
|
}
|
||||||
new InstallMethodDialog(activity, options, filename).show();
|
new InstallMethodDialog(activity, options).show();
|
||||||
});
|
});
|
||||||
setNegativeButton(R.string.no_thanks, null);
|
setNegativeButton(R.string.no_thanks, null);
|
||||||
if (!TextUtils.isEmpty(Data.magiskNoteLink)) {
|
if (!TextUtils.isEmpty(Data.magiskNoteLink)) {
|
||||||
|
@ -4,6 +4,7 @@ import android.content.ContentValues;
|
|||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
|
|
||||||
import com.topjohnwu.magisk.Const;
|
import com.topjohnwu.magisk.Const;
|
||||||
|
import com.topjohnwu.magisk.utils.Download;
|
||||||
import com.topjohnwu.magisk.utils.Logger;
|
import com.topjohnwu.magisk.utils.Logger;
|
||||||
import com.topjohnwu.magisk.utils.Utils;
|
import com.topjohnwu.magisk.utils.Utils;
|
||||||
import com.topjohnwu.magisk.utils.WebService;
|
import com.topjohnwu.magisk.utils.WebService;
|
||||||
@ -82,6 +83,10 @@ public class Repo extends BaseModule {
|
|||||||
return mLastUpdate;
|
return mLastUpdate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getDownloadFilename() {
|
||||||
|
return Download.getLegalFilename(getName() + "-" + getVersion() + ".zip");
|
||||||
|
}
|
||||||
|
|
||||||
public class IllegalRepoException extends Exception {
|
public class IllegalRepoException extends Exception {
|
||||||
IllegalRepoException(String message) {
|
IllegalRepoException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
|
@ -12,6 +12,7 @@ import android.widget.Toast;
|
|||||||
|
|
||||||
import com.topjohnwu.magisk.NoUIActivity;
|
import com.topjohnwu.magisk.NoUIActivity;
|
||||||
import com.topjohnwu.magisk.R;
|
import com.topjohnwu.magisk.R;
|
||||||
|
import com.topjohnwu.magisk.utils.Download;
|
||||||
|
|
||||||
public abstract class BaseActivity extends FlavorActivity {
|
public abstract class BaseActivity extends FlavorActivity {
|
||||||
|
|
||||||
@ -26,6 +27,7 @@ public abstract class BaseActivity extends FlavorActivity {
|
|||||||
granted = false;
|
granted = false;
|
||||||
}
|
}
|
||||||
if (granted) {
|
if (granted) {
|
||||||
|
Download.EXTERNAL_PATH.mkdirs();
|
||||||
callback.run();
|
callback.run();
|
||||||
} else {
|
} else {
|
||||||
// Passed in context should be an activity if not granted, need to show dialog!
|
// Passed in context should be an activity if not granted, need to show dialog!
|
||||||
|
@ -10,6 +10,7 @@ import android.net.Uri;
|
|||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.topjohnwu.magisk.Data;
|
||||||
import com.topjohnwu.magisk.R;
|
import com.topjohnwu.magisk.R;
|
||||||
import com.topjohnwu.magisk.components.BaseActivity;
|
import com.topjohnwu.magisk.components.BaseActivity;
|
||||||
import com.topjohnwu.magisk.receivers.DownloadReceiver;
|
import com.topjohnwu.magisk.receivers.DownloadReceiver;
|
||||||
@ -19,7 +20,11 @@ import java.io.File;
|
|||||||
public class Download {
|
public class Download {
|
||||||
|
|
||||||
public static final File EXTERNAL_PATH =
|
public static final File EXTERNAL_PATH =
|
||||||
new File(Environment.getExternalStorageDirectory(), "MagiskManager");
|
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
|
||||||
|
|
||||||
|
static {
|
||||||
|
EXTERNAL_PATH.mkdirs();
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean isDownloading = false;
|
public static boolean isDownloading = false;
|
||||||
|
|
||||||
@ -30,11 +35,7 @@ public class Download {
|
|||||||
BaseActivity.runWithPermission(context,
|
BaseActivity.runWithPermission(context,
|
||||||
new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE }, () -> {
|
new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE }, () -> {
|
||||||
File file = new File(EXTERNAL_PATH, getLegalFilename(filename));
|
File file = new File(EXTERNAL_PATH, getLegalFilename(filename));
|
||||||
|
file.delete();
|
||||||
if ((!file.getParentFile().exists() && !file.getParentFile().mkdirs())
|
|
||||||
|| (file.exists() && !file.delete())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Toast.makeText(context, context.getString(R.string.downloading_toast, filename),
|
Toast.makeText(context, context.getString(R.string.downloading_toast, filename),
|
||||||
Toast.LENGTH_LONG).show();
|
Toast.LENGTH_LONG).show();
|
||||||
|
Loading…
Reference in New Issue
Block a user