Choices on duplicate icon pack
This commit is contained in:
parent
d25799719e
commit
596bd7bc08
@ -19,6 +19,7 @@ import androidx.core.util.Consumer;
|
|||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
|
||||||
import com.cringe_studios.code_guard.databinding.ActivityMainBinding;
|
import com.cringe_studios.code_guard.databinding.ActivityMainBinding;
|
||||||
|
import com.cringe_studios.code_guard.databinding.DialogIconPackExistsBinding;
|
||||||
import com.cringe_studios.code_guard.databinding.DialogInputCodeChoiceBinding;
|
import com.cringe_studios.code_guard.databinding.DialogInputCodeChoiceBinding;
|
||||||
import com.cringe_studios.code_guard.fragment.AboutFragment;
|
import com.cringe_studios.code_guard.fragment.AboutFragment;
|
||||||
import com.cringe_studios.code_guard.fragment.EditOTPFragment;
|
import com.cringe_studios.code_guard.fragment.EditOTPFragment;
|
||||||
@ -26,6 +27,7 @@ import com.cringe_studios.code_guard.fragment.GroupFragment;
|
|||||||
import com.cringe_studios.code_guard.fragment.HomeFragment;
|
import com.cringe_studios.code_guard.fragment.HomeFragment;
|
||||||
import com.cringe_studios.code_guard.fragment.NamedFragment;
|
import com.cringe_studios.code_guard.fragment.NamedFragment;
|
||||||
import com.cringe_studios.code_guard.fragment.SettingsFragment;
|
import com.cringe_studios.code_guard.fragment.SettingsFragment;
|
||||||
|
import com.cringe_studios.code_guard.icon.IconPack;
|
||||||
import com.cringe_studios.code_guard.icon.IconPackException;
|
import com.cringe_studios.code_guard.icon.IconPackException;
|
||||||
import com.cringe_studios.code_guard.icon.IconPackMetadata;
|
import com.cringe_studios.code_guard.icon.IconPackMetadata;
|
||||||
import com.cringe_studios.code_guard.icon.IconUtil;
|
import com.cringe_studios.code_guard.icon.IconUtil;
|
||||||
@ -146,7 +148,9 @@ public class MainActivity extends BaseActivity {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
if(doc == null) return;
|
if(doc == null) return;
|
||||||
IconPackMetadata meta = IconUtil.importIconPack(this, doc);
|
IconPackMetadata meta = IconUtil.loadPackMetadata(this, doc);
|
||||||
|
|
||||||
|
IconPack existingIconPack = IconUtil.loadIconPack(this, meta.getUuid());
|
||||||
|
|
||||||
if(!meta.validate()) {
|
if(!meta.validate()) {
|
||||||
DialogUtil.showErrorDialog(this, getString(R.string.error_icon_pack_invalid));
|
DialogUtil.showErrorDialog(this, getString(R.string.error_icon_pack_invalid));
|
||||||
@ -158,7 +162,57 @@ public class MainActivity extends BaseActivity {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DialogUtil.showErrorDialog(this, "Icon pack contains " + meta.getIcons().length + " icons");
|
if(existingIconPack != null) {
|
||||||
|
DialogIconPackExistsBinding binding = DialogIconPackExistsBinding.inflate(getLayoutInflater());
|
||||||
|
binding.iconPackExistsText.setText(getString(R.string.error_icon_pack_exists, meta.getName(), meta.getVersion(), existingIconPack.getMetadata().getName(), existingIconPack.getMetadata().getVersion()));
|
||||||
|
binding.iconPackExistsChoices.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, getResources().getStringArray(R.array.error_icon_pack_exists_choices)));
|
||||||
|
|
||||||
|
|
||||||
|
AlertDialog dialog = new StyledDialogBuilder(this)
|
||||||
|
.setTitle("Icon pack already exists")
|
||||||
|
.setView(binding.getRoot())
|
||||||
|
.setNeutralButton(R.string.cancel, (d, which) -> {})
|
||||||
|
.create();
|
||||||
|
|
||||||
|
binding.iconPackExistsChoices.setOnItemClickListener((parent, view, position, id) -> {
|
||||||
|
switch(position) {
|
||||||
|
case 0: // Override
|
||||||
|
try {
|
||||||
|
IconUtil.importIconPack(this, doc);
|
||||||
|
Toast.makeText(this, getString(R.string.icon_pack_imported, meta.getIcons().length), Toast.LENGTH_LONG).show();
|
||||||
|
} catch (IconPackException e) {
|
||||||
|
DialogUtil.showErrorDialog(this, "Failed to import icon pack", e);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1: // Rename existing
|
||||||
|
try {
|
||||||
|
IconUtil.renameIconPack(this, existingIconPack, existingIconPack.getMetadata().getName() + " (" + existingIconPack.getMetadata().getVersion() + ")", UUID.randomUUID().toString());
|
||||||
|
IconUtil.importIconPack(this, doc);
|
||||||
|
Toast.makeText(this, getString(R.string.icon_pack_imported, meta.getIcons().length), Toast.LENGTH_LONG).show();
|
||||||
|
} catch (IconPackException e) {
|
||||||
|
DialogUtil.showErrorDialog(this, "Failed to import icon pack", e);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2: // Rename imported
|
||||||
|
try {
|
||||||
|
IconUtil.importIconPack(this, doc, meta.getName() + "(" + meta.getVersion() + ")", UUID.randomUUID().toString());
|
||||||
|
Toast.makeText(this, getString(R.string.icon_pack_imported, meta.getIcons().length), Toast.LENGTH_LONG).show();
|
||||||
|
} catch (IconPackException e) {
|
||||||
|
DialogUtil.showErrorDialog(this, "Failed to import icon pack", e);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog.dismiss();
|
||||||
|
});
|
||||||
|
|
||||||
|
dialog.show();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IconUtil.importIconPack(this, doc);
|
||||||
|
Toast.makeText(this, getString(R.string.icon_pack_imported, meta.getIcons().length), Toast.LENGTH_LONG).show();
|
||||||
} catch (IconPackException e) {
|
} catch (IconPackException e) {
|
||||||
DialogUtil.showErrorDialog(this, "Failed to import icon pack", e);
|
DialogUtil.showErrorDialog(this, "Failed to import icon pack", e);
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,7 @@ import com.cringe_studios.code_guard.util.SettingsUtil;
|
|||||||
import com.cringe_studios.code_guard.util.StyledDialogBuilder;
|
import com.cringe_studios.code_guard.util.StyledDialogBuilder;
|
||||||
import com.cringe_studios.code_guard.util.Theme;
|
import com.cringe_studios.code_guard.util.Theme;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
@ -264,7 +265,17 @@ public class SettingsFragment extends NamedFragment {
|
|||||||
binding.settingsLoadIconPack.setOnClickListener(v -> ((MainActivity) requireActivity()).promptPickIconPackFile());
|
binding.settingsLoadIconPack.setOnClickListener(v -> ((MainActivity) requireActivity()).promptPickIconPackFile());
|
||||||
|
|
||||||
binding.settingsManageIconPacks.setOnClickListener(v -> {
|
binding.settingsManageIconPacks.setOnClickListener(v -> {
|
||||||
List<IconPack> packs = IconUtil.loadAllIconPacks(requireContext());
|
List<String> brokenPacks = new ArrayList<>();
|
||||||
|
List<IconPack> packs = IconUtil.loadAllIconPacks(requireContext(), brokenPacks::add);
|
||||||
|
|
||||||
|
if(!brokenPacks.isEmpty()) {
|
||||||
|
DialogUtil.showYesNo(requireContext(), R.string.broken_icon_packs_title, R.string.broken_icon_packs_message, () -> {
|
||||||
|
for(String pack : brokenPacks) {
|
||||||
|
IconUtil.removeIconPack(requireContext(), pack);
|
||||||
|
}
|
||||||
|
}, null);
|
||||||
|
}
|
||||||
|
|
||||||
if(packs.isEmpty()) {
|
if(packs.isEmpty()) {
|
||||||
Toast.makeText(requireContext(), R.string.no_icon_packs_installed, Toast.LENGTH_LONG).show();
|
Toast.makeText(requireContext(), R.string.no_icon_packs_installed, Toast.LENGTH_LONG).show();
|
||||||
return;
|
return;
|
||||||
|
@ -41,7 +41,13 @@ public class IconPackListAdapter extends RecyclerView.Adapter<IconPackItem> {
|
|||||||
holder.getBinding().iconPackName.setText(pack.getMetadata().getName());
|
holder.getBinding().iconPackName.setText(pack.getMetadata().getName());
|
||||||
|
|
||||||
holder.getBinding().iconPackDelete.setOnClickListener(view -> {
|
holder.getBinding().iconPackDelete.setOnClickListener(view -> {
|
||||||
DialogUtil.showYesNo(context, R.string.delete_pack_title, R.string.delete_pack_message, () -> IconUtil.removeIconPack(context, pack.getMetadata().getUuid()), null);
|
DialogUtil.showYesNo(context, R.string.delete_pack_title, R.string.delete_pack_message, () -> {
|
||||||
|
IconUtil.removeIconPack(context, pack.getMetadata().getUuid());
|
||||||
|
|
||||||
|
int idx = packs.indexOf(pack);
|
||||||
|
packs.remove(idx);
|
||||||
|
notifyItemRemoved(idx);
|
||||||
|
}, null);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,10 +9,18 @@ public class IconPackMetadata {
|
|||||||
|
|
||||||
private IconPackMetadata() {}
|
private IconPackMetadata() {}
|
||||||
|
|
||||||
|
public void setUuid(String uuid) {
|
||||||
|
this.uuid = uuid;
|
||||||
|
}
|
||||||
|
|
||||||
public String getUuid() {
|
public String getUuid() {
|
||||||
return uuid;
|
return uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
@ -17,13 +17,15 @@ import com.caverock.androidsvg.SVG;
|
|||||||
import com.caverock.androidsvg.SVGImageView;
|
import com.caverock.androidsvg.SVGImageView;
|
||||||
import com.caverock.androidsvg.SVGParseException;
|
import com.caverock.androidsvg.SVGParseException;
|
||||||
import com.cringe_studios.code_guard.model.OTPData;
|
import com.cringe_studios.code_guard.model.OTPData;
|
||||||
import com.cringe_studios.code_guard.util.DialogUtil;
|
|
||||||
import com.cringe_studios.code_guard.util.IOUtil;
|
import com.cringe_studios.code_guard.util.IOUtil;
|
||||||
import com.cringe_studios.code_guard.util.SettingsUtil;
|
import com.cringe_studios.code_guard.util.SettingsUtil;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.BufferedOutputStream;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@ -38,6 +40,7 @@ import java.util.Map;
|
|||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
import java.util.zip.ZipInputStream;
|
import java.util.zip.ZipInputStream;
|
||||||
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
public class IconUtil {
|
public class IconUtil {
|
||||||
|
|
||||||
@ -79,10 +82,9 @@ public class IconUtil {
|
|||||||
return iconPacksDir;
|
return iconPacksDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IconPackMetadata importIconPack(Context context, Uri uri) throws IconPackException {
|
public static void importIconPack(Context context, Uri uri) throws IconPackException {
|
||||||
IconPackMetadata meta = loadPackMetadata(context, uri);
|
IconPackMetadata meta = loadPackMetadata(context, uri);
|
||||||
|
|
||||||
// TODO: check for existing icon pack
|
|
||||||
File iconPackFile = new File(getIconPacksDir(context), meta.getUuid());
|
File iconPackFile = new File(getIconPacksDir(context), meta.getUuid());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -90,7 +92,7 @@ public class IconUtil {
|
|||||||
iconPackFile.createNewFile();
|
iconPackFile.createNewFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
try (OutputStream out = new FileOutputStream(iconPackFile);
|
try (OutputStream out = new BufferedOutputStream(new FileOutputStream(iconPackFile));
|
||||||
InputStream in = context.getContentResolver().openInputStream(uri)) {
|
InputStream in = context.getContentResolver().openInputStream(uri)) {
|
||||||
if(in == null) throw new IconPackException("Failed to read icon pack");
|
if(in == null) throw new IconPackException("Failed to read icon pack");
|
||||||
byte[] bytes = IOUtil.readBytes(in);
|
byte[] bytes = IOUtil.readBytes(in);
|
||||||
@ -99,8 +101,54 @@ public class IconUtil {
|
|||||||
}catch(IOException e) {
|
}catch(IOException e) {
|
||||||
throw new IconPackException("Failed to import icon pack", e);
|
throw new IconPackException("Failed to import icon pack", e);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return meta;
|
public static void importIconPack(Context context, Uri uri, String newName, String newUUID) throws IconPackException {
|
||||||
|
IconPackMetadata meta = loadPackMetadata(context, uri);
|
||||||
|
meta.setName(newName);
|
||||||
|
meta.setUuid(newUUID);
|
||||||
|
|
||||||
|
File iconPackFile = new File(getIconPacksDir(context), meta.getUuid());
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!iconPackFile.exists()) {
|
||||||
|
iconPackFile.createNewFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
try (InputStream in = context.getContentResolver().openInputStream(uri)) {
|
||||||
|
if(in == null) throw new IconPackException("Failed to read icon pack");
|
||||||
|
writeRenamedPack(in, iconPackFile, meta);
|
||||||
|
}
|
||||||
|
}catch(IOException e) {
|
||||||
|
throw new IconPackException("Failed to import icon pack", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void renameIconPack(Context context, IconPack pack, String newName, String newUUID) throws IconPackException {
|
||||||
|
File packFile = new File(getIconPacksDir(context), pack.getMetadata().getUuid());
|
||||||
|
if(!packFile.exists()) return;
|
||||||
|
|
||||||
|
File newPackFile = new File(getIconPacksDir(context), newUUID);
|
||||||
|
|
||||||
|
String oldName = pack.getMetadata().getName();
|
||||||
|
String oldUUID = pack.getMetadata().getUuid();
|
||||||
|
|
||||||
|
|
||||||
|
loadedPacks.remove(oldUUID);
|
||||||
|
|
||||||
|
pack.getMetadata().setName(newName);
|
||||||
|
pack.getMetadata().setUuid(newUUID);
|
||||||
|
|
||||||
|
try {
|
||||||
|
writeRenamedPack(new BufferedInputStream(new FileInputStream(packFile)), newPackFile, pack.getMetadata());
|
||||||
|
packFile.delete();
|
||||||
|
}catch(IconPackException e) {
|
||||||
|
pack.getMetadata().setName(oldName);
|
||||||
|
pack.getMetadata().setUuid(oldUUID);
|
||||||
|
throw e;
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
throw new IconPackException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void removeIconPack(Context context, String uuid) {
|
public static void removeIconPack(Context context, String uuid) {
|
||||||
@ -109,12 +157,14 @@ public class IconUtil {
|
|||||||
loadedPacks.remove(uuid);
|
loadedPacks.remove(uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IconPackMetadata loadPackMetadata(Context context, Uri uri) throws IconPackException {
|
public static IconPackMetadata loadPackMetadata(Context context, Uri uri) throws IconPackException {
|
||||||
try(InputStream in = context.getContentResolver().openInputStream(uri)) {
|
try(InputStream in = context.getContentResolver().openInputStream(uri)) {
|
||||||
if(in == null) throw new IconPackException("Failed to read icon pack");
|
if(in == null) throw new IconPackException("Failed to read icon pack");
|
||||||
try(ZipInputStream zIn = new ZipInputStream(in)) {
|
try(ZipInputStream zIn = new ZipInputStream(in)) {
|
||||||
ZipEntry en;
|
ZipEntry en;
|
||||||
while((en = zIn.getNextEntry()) != null) {
|
while((en = zIn.getNextEntry()) != null) {
|
||||||
|
if(en.isDirectory()) continue;
|
||||||
|
|
||||||
if(en.getName().equals("pack.json")) {
|
if(en.getName().equals("pack.json")) {
|
||||||
byte[] entryBytes = readEntry(zIn, en);
|
byte[] entryBytes = readEntry(zIn, en);
|
||||||
return SettingsUtil.GSON.fromJson(new String(entryBytes, StandardCharsets.UTF_8), IconPackMetadata.class); // TODO: validate metadata
|
return SettingsUtil.GSON.fromJson(new String(entryBytes, StandardCharsets.UTF_8), IconPackMetadata.class); // TODO: validate metadata
|
||||||
@ -128,6 +178,28 @@ public class IconUtil {
|
|||||||
throw new IconPackException("No pack.json");
|
throw new IconPackException("No pack.json");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void writeRenamedPack(InputStream oldFile, File newFile, IconPackMetadata meta) throws IconPackException {
|
||||||
|
try(ZipInputStream in = new ZipInputStream(oldFile);
|
||||||
|
ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(newFile)))) {
|
||||||
|
ZipEntry en;
|
||||||
|
while((en = in.getNextEntry()) != null) {
|
||||||
|
if(en.isDirectory()) continue;
|
||||||
|
|
||||||
|
byte[] entryBytes = readEntry(in, en);
|
||||||
|
if(en.getName().equals("pack.json")) {
|
||||||
|
out.putNextEntry(new ZipEntry("pack.json"));
|
||||||
|
out.write(SettingsUtil.GSON.toJson(meta).getBytes(StandardCharsets.UTF_8));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
out.putNextEntry(new ZipEntry(en.getName()));
|
||||||
|
out.write(entryBytes);
|
||||||
|
}
|
||||||
|
}catch(IOException e) {
|
||||||
|
throw new IconPackException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static Map<String, List<Icon>> loadAllIcons(Context context) {
|
public static Map<String, List<Icon>> loadAllIcons(Context context) {
|
||||||
List<IconPack> packs = loadAllIconPacks(context);
|
List<IconPack> packs = loadAllIconPacks(context);
|
||||||
|
|
||||||
@ -148,7 +220,7 @@ public class IconUtil {
|
|||||||
return icons;
|
return icons;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<IconPack> loadAllIconPacks(Context context) {
|
public static List<IconPack> loadAllIconPacks(Context context, Consumer<String> brokenPack) {
|
||||||
File iconPacksDir = getIconPacksDir(context);
|
File iconPacksDir = getIconPacksDir(context);
|
||||||
|
|
||||||
String[] packIDs = iconPacksDir.list();
|
String[] packIDs = iconPacksDir.list();
|
||||||
@ -157,15 +229,24 @@ public class IconUtil {
|
|||||||
List<IconPack> packs = new ArrayList<>();
|
List<IconPack> packs = new ArrayList<>();
|
||||||
for(String pack : packIDs) {
|
for(String pack : packIDs) {
|
||||||
try {
|
try {
|
||||||
packs.add(loadIconPack(context, pack));
|
IconPack p = loadIconPack(context, pack);
|
||||||
|
if(p == null) continue;
|
||||||
|
if(!p.getMetadata().getUuid().equals(pack)) throw new IconPackException("Invalid metadata");
|
||||||
|
packs.add(p);
|
||||||
}catch(IconPackException e) {
|
}catch(IconPackException e) {
|
||||||
DialogUtil.showErrorDialog(context, "An icon pack failed to load", e);
|
e.printStackTrace();
|
||||||
|
if(brokenPack != null) brokenPack.accept(pack);
|
||||||
|
//DialogUtil.showErrorDialog(context, "An icon pack failed to load", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return packs;
|
return packs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<IconPack> loadAllIconPacks(Context context) {
|
||||||
|
return loadAllIconPacks(context, null);
|
||||||
|
}
|
||||||
|
|
||||||
public static IconPack loadIconPack(Context context, String uuid) throws IconPackException {
|
public static IconPack loadIconPack(Context context, String uuid) throws IconPackException {
|
||||||
if(loadedPacks.containsKey(uuid)) return loadedPacks.get(uuid);
|
if(loadedPacks.containsKey(uuid)) return loadedPacks.get(uuid);
|
||||||
|
|
||||||
@ -179,12 +260,14 @@ public class IconUtil {
|
|||||||
private static IconPack loadIconPack(File file) throws IconPackException {
|
private static IconPack loadIconPack(File file) throws IconPackException {
|
||||||
if(!file.exists()) return null;
|
if(!file.exists()) return null;
|
||||||
|
|
||||||
try(ZipInputStream in = new ZipInputStream(new FileInputStream(file))) {
|
try(ZipInputStream in = new ZipInputStream(new BufferedInputStream(new FileInputStream(file)))) {
|
||||||
IconPackMetadata metadata = null;
|
IconPackMetadata metadata = null;
|
||||||
Map<String, byte[]> files = new HashMap<>();
|
Map<String, byte[]> files = new HashMap<>();
|
||||||
|
|
||||||
ZipEntry en;
|
ZipEntry en;
|
||||||
while((en = in.getNextEntry()) != null) {
|
while((en = in.getNextEntry()) != null) {
|
||||||
|
if(en.isDirectory()) continue;
|
||||||
|
|
||||||
byte[] entryBytes = readEntry(in, en);
|
byte[] entryBytes = readEntry(in, en);
|
||||||
|
|
||||||
if(en.getName().equals("pack.json")) {
|
if(en.getName().equals("pack.json")) {
|
||||||
@ -214,18 +297,11 @@ public class IconUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] readEntry(ZipInputStream in, ZipEntry en) throws IOException {
|
private static byte[] readEntry(ZipInputStream in, ZipEntry en) throws IOException {
|
||||||
if (en.getSize() < 0 || en.getSize() > Integer.MAX_VALUE) {
|
if (en.getSize() > Integer.MAX_VALUE) {
|
||||||
throw new IOException("Invalid ZIP entry");
|
throw new IOException("Invalid ZIP entry");
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] entryBytes = new byte[(int) en.getSize()];
|
return IOUtil.readBytes(in);
|
||||||
|
|
||||||
int totalRead = 0;
|
|
||||||
while (totalRead < entryBytes.length) {
|
|
||||||
totalRead += in.read(entryBytes, totalRead, entryBytes.length - totalRead);
|
|
||||||
}
|
|
||||||
|
|
||||||
return entryBytes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Bitmap generateCodeImage(String issuer, String name) {
|
public static Bitmap generateCodeImage(String issuer, String name) {
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package com.cringe_studios.code_guard.util;
|
package com.cringe_studios.code_guard.util;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
@ -11,7 +11,7 @@ import java.nio.ByteBuffer;
|
|||||||
public class IOUtil {
|
public class IOUtil {
|
||||||
|
|
||||||
public static byte[] readBytes(File file) throws IOException {
|
public static byte[] readBytes(File file) throws IOException {
|
||||||
try(FileInputStream fIn = new FileInputStream(file)) {
|
try(InputStream fIn = new BufferedInputStream(new FileInputStream(file))) {
|
||||||
ByteBuffer fileBuffer = ByteBuffer.allocate((int) file.length());
|
ByteBuffer fileBuffer = ByteBuffer.allocate((int) file.length());
|
||||||
byte[] buffer = new byte[1024];
|
byte[] buffer = new byte[1024];
|
||||||
int len;
|
int len;
|
||||||
@ -34,10 +34,4 @@ public class IOUtil {
|
|||||||
return bOut.toByteArray();
|
return bOut.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void writeBytes(File file, byte[] bytes) throws IOException {
|
|
||||||
try(FileOutputStream fOut = new FileOutputStream(file)) {
|
|
||||||
fOut.write(bytes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -11,9 +11,11 @@ import com.cringe_studios.code_guard.model.OTPData;
|
|||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.google.gson.JsonSyntaxException;
|
import com.google.gson.JsonSyntaxException;
|
||||||
|
|
||||||
|
import java.io.BufferedOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -148,7 +150,7 @@ public class OTPDatabase {
|
|||||||
|
|
||||||
byte[] dbBytes = convertToEncryptedBytes(loadedDatabase, loadedKey, parameters);
|
byte[] dbBytes = convertToEncryptedBytes(loadedDatabase, loadedKey, parameters);
|
||||||
|
|
||||||
try(FileOutputStream fOut = new FileOutputStream(file)) {
|
try(OutputStream fOut = new BufferedOutputStream(new FileOutputStream(file))) {
|
||||||
fOut.write(dbBytes);
|
fOut.write(dbBytes);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new OTPDatabaseException(e);
|
throw new OTPDatabaseException(e);
|
||||||
|
22
app/src/main/res/layout/dialog_icon_pack_exists.xml
Normal file
22
app/src/main/res/layout/dialog_icon_pack_exists.xml
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/icon_pack_exists_text"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
tools:text="@string/error_icon_pack_exists" />
|
||||||
|
|
||||||
|
<ListView
|
||||||
|
android:id="@+id/icon_pack_exists_choices"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
tools:listitem="@android:layout/simple_list_item_1"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
@ -123,4 +123,13 @@
|
|||||||
<string name="patreon_link" translatable="false">https://git.cringe-studios.com/CringeStudios/Code-Guard</string>
|
<string name="patreon_link" translatable="false">https://git.cringe-studios.com/CringeStudios/Code-Guard</string>
|
||||||
<string name="error_icon_pack_empty">The icon pack doesn\'t contain any icons</string>
|
<string name="error_icon_pack_empty">The icon pack doesn\'t contain any icons</string>
|
||||||
<string name="error_icon_pack_invalid">Pack contains invalid metadata. Make sure you selected the correct file</string>
|
<string name="error_icon_pack_invalid">Pack contains invalid metadata. Make sure you selected the correct file</string>
|
||||||
|
<string name="error_icon_pack_exists">The icon pack you\'re trying to import already exists.\n\nImported: %s (version %d)\nExisting: %s (version %d)\n\nWhat do you want to do?</string>
|
||||||
|
<string name="broken_icon_packs_title">Broken icon packs</string>
|
||||||
|
<string name="broken_icon_packs_message">Some icon packs failed to load.\n\nDo you want to delete the broken icon packs?</string>
|
||||||
|
<string name="icon_pack_imported">Icon pack with %d icon(s) imported</string>
|
||||||
|
<string-array name="error_icon_pack_exists_choices">
|
||||||
|
<item>Override</item>
|
||||||
|
<item>Rename existing</item>
|
||||||
|
<item>Rename imported</item>
|
||||||
|
</string-array>
|
||||||
</resources>
|
</resources>
|
Loading…
Reference in New Issue
Block a user