mirror of
https://github.com/beemdevelopment/Aegis.git
synced 2025-04-18 13:02:06 +00:00
Merge pull request #1591 from alexbakker/resize-icons
Store non-SVG icons at a maximum of 512x512 and migrate existing icons
This commit is contained in:
commit
ec92fb2b31
11 changed files with 224 additions and 22 deletions
|
@ -1,6 +1,13 @@
|
|||
package com.beemdevelopment.aegis.helpers;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
|
||||
import com.beemdevelopment.aegis.icons.IconType;
|
||||
import com.beemdevelopment.aegis.vault.VaultEntryIcon;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.Objects;
|
||||
|
||||
public class BitmapHelper {
|
||||
private BitmapHelper() {
|
||||
|
@ -28,4 +35,29 @@ public class BitmapHelper {
|
|||
|
||||
return Bitmap.createScaledBitmap(bitmap, width, height, true);
|
||||
}
|
||||
|
||||
public static boolean isVaultEntryIconOptimized(VaultEntryIcon icon) {
|
||||
BitmapFactory.Options opts = new BitmapFactory.Options();
|
||||
opts.inJustDecodeBounds = true;
|
||||
BitmapFactory.decodeByteArray(icon.getBytes(), 0, icon.getBytes().length, opts);
|
||||
return opts.outWidth <= VaultEntryIcon.MAX_DIMENS && opts.outHeight <= VaultEntryIcon.MAX_DIMENS;
|
||||
}
|
||||
|
||||
public static VaultEntryIcon toVaultEntryIcon(Bitmap bitmap, IconType iconType) {
|
||||
if (bitmap.getWidth() > VaultEntryIcon.MAX_DIMENS
|
||||
|| bitmap.getHeight() > VaultEntryIcon.MAX_DIMENS) {
|
||||
bitmap = resize(bitmap, VaultEntryIcon.MAX_DIMENS, VaultEntryIcon.MAX_DIMENS);
|
||||
}
|
||||
|
||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||
if (Objects.equals(iconType, IconType.PNG)) {
|
||||
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
|
||||
} else {
|
||||
iconType = IconType.JPEG;
|
||||
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, stream);
|
||||
}
|
||||
|
||||
byte[] data = stream.toByteArray();
|
||||
return new VaultEntryIcon(data, iconType);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,12 +35,14 @@ import com.beemdevelopment.aegis.encoding.Base32;
|
|||
import com.beemdevelopment.aegis.encoding.EncodingException;
|
||||
import com.beemdevelopment.aegis.encoding.Hex;
|
||||
import com.beemdevelopment.aegis.helpers.AnimationsHelper;
|
||||
import com.beemdevelopment.aegis.helpers.BitmapHelper;
|
||||
import com.beemdevelopment.aegis.helpers.DropdownHelper;
|
||||
import com.beemdevelopment.aegis.helpers.EditTextHelper;
|
||||
import com.beemdevelopment.aegis.helpers.SafHelper;
|
||||
import com.beemdevelopment.aegis.helpers.SimpleAnimationEndListener;
|
||||
import com.beemdevelopment.aegis.helpers.SimpleTextWatcher;
|
||||
import com.beemdevelopment.aegis.helpers.TextDrawableHelper;
|
||||
import com.beemdevelopment.aegis.helpers.ViewHelper;
|
||||
import com.beemdevelopment.aegis.icons.IconPack;
|
||||
import com.beemdevelopment.aegis.icons.IconType;
|
||||
import com.beemdevelopment.aegis.otp.GoogleAuthInfo;
|
||||
|
@ -59,7 +61,6 @@ import com.beemdevelopment.aegis.ui.tasks.ImportFileTask;
|
|||
import com.beemdevelopment.aegis.ui.views.IconAdapter;
|
||||
import com.beemdevelopment.aegis.util.Cloner;
|
||||
import com.beemdevelopment.aegis.util.IOUtils;
|
||||
import com.beemdevelopment.aegis.helpers.ViewHelper;
|
||||
import com.beemdevelopment.aegis.vault.VaultEntry;
|
||||
import com.beemdevelopment.aegis.vault.VaultEntryIcon;
|
||||
import com.beemdevelopment.aegis.vault.VaultGroup;
|
||||
|
@ -76,7 +77,6 @@ import com.google.android.material.imageview.ShapeableImageView;
|
|||
import com.google.android.material.textfield.TextInputEditText;
|
||||
import com.google.android.material.textfield.TextInputLayout;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
|
@ -103,6 +103,7 @@ public class EditEntryActivity extends AegisActivity {
|
|||
// keep track of icon changes separately as the generated jpeg's are not deterministic
|
||||
private boolean _hasChangedIcon = false;
|
||||
private IconPack.Icon _selectedIcon;
|
||||
private String _pickedMimeType;
|
||||
private ShapeableImageView _iconView;
|
||||
private ImageView _saveImageButton;
|
||||
|
||||
|
@ -140,8 +141,8 @@ public class EditEntryActivity extends AegisActivity {
|
|||
if (activityResult.getResultCode() != RESULT_OK || data == null || data.getData() == null) {
|
||||
return;
|
||||
}
|
||||
String fileType = SafHelper.getMimeType(this, data.getData());
|
||||
if (fileType != null && fileType.equals(IconType.SVG.toMimeType())) {
|
||||
_pickedMimeType = SafHelper.getMimeType(this, data.getData());
|
||||
if (_pickedMimeType != null && _pickedMimeType.equals(IconType.SVG.toMimeType())) {
|
||||
ImportFileTask.Params params = new ImportFileTask.Params(data.getData(), "icon", null);
|
||||
ImportFileTask task = new ImportFileTask(this, result -> {
|
||||
if (result.getError() == null) {
|
||||
|
@ -804,11 +805,12 @@ public class EditEntryActivity extends AegisActivity {
|
|||
VaultEntryIcon icon;
|
||||
if (_selectedIcon == null) {
|
||||
Bitmap bitmap = ((BitmapDrawable) _iconView.getDrawable()).getBitmap();
|
||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||
// the quality parameter is ignored for PNG
|
||||
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
|
||||
byte[] data = stream.toByteArray();
|
||||
icon = new VaultEntryIcon(data, IconType.PNG);
|
||||
IconType iconType = _pickedMimeType == null
|
||||
? IconType.INVALID : IconType.fromMimeType(_pickedMimeType);
|
||||
if (iconType == IconType.INVALID) {
|
||||
iconType = bitmap.hasAlpha() ? IconType.PNG : IconType.JPEG;
|
||||
}
|
||||
icon = BitmapHelper.toVaultEntryIcon(bitmap, iconType);
|
||||
} else {
|
||||
byte[] iconBytes;
|
||||
try (FileInputStream inStream = new FileInputStream(_selectedIcon.getFile())){
|
||||
|
|
|
@ -15,17 +15,21 @@ import androidx.recyclerview.widget.LinearLayoutManager;
|
|||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.beemdevelopment.aegis.R;
|
||||
import com.beemdevelopment.aegis.helpers.BitmapHelper;
|
||||
import com.beemdevelopment.aegis.helpers.FabScrollHelper;
|
||||
import com.beemdevelopment.aegis.helpers.ViewHelper;
|
||||
import com.beemdevelopment.aegis.icons.IconType;
|
||||
import com.beemdevelopment.aegis.importers.DatabaseImporter;
|
||||
import com.beemdevelopment.aegis.importers.DatabaseImporterEntryException;
|
||||
import com.beemdevelopment.aegis.importers.DatabaseImporterException;
|
||||
import com.beemdevelopment.aegis.ui.dialogs.Dialogs;
|
||||
import com.beemdevelopment.aegis.ui.models.ImportEntry;
|
||||
import com.beemdevelopment.aegis.ui.tasks.IconOptimizationTask;
|
||||
import com.beemdevelopment.aegis.ui.tasks.RootShellTask;
|
||||
import com.beemdevelopment.aegis.ui.views.ImportEntriesAdapter;
|
||||
import com.beemdevelopment.aegis.util.UUIDMap;
|
||||
import com.beemdevelopment.aegis.helpers.ViewHelper;
|
||||
import com.beemdevelopment.aegis.vault.VaultEntry;
|
||||
import com.beemdevelopment.aegis.vault.VaultEntryIcon;
|
||||
import com.beemdevelopment.aegis.vault.VaultGroup;
|
||||
import com.beemdevelopment.aegis.vault.VaultRepository;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
|
@ -40,8 +44,10 @@ import java.io.InputStream;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ImportEntriesActivity extends AegisActivity {
|
||||
private View _view;
|
||||
|
@ -172,7 +178,7 @@ public class ImportEntriesActivity extends AegisActivity {
|
|||
state.decrypt(this, new DatabaseImporter.DecryptListener() {
|
||||
@Override
|
||||
public void onStateDecrypted(DatabaseImporter.State state) {
|
||||
importDatabase(state);
|
||||
processDecryptedImporterState(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -187,7 +193,7 @@ public class ImportEntriesActivity extends AegisActivity {
|
|||
}
|
||||
});
|
||||
} else {
|
||||
importDatabase(state);
|
||||
processDecryptedImporterState(state);
|
||||
}
|
||||
} catch (DatabaseImporterException e) {
|
||||
e.printStackTrace();
|
||||
|
@ -195,8 +201,7 @@ public class ImportEntriesActivity extends AegisActivity {
|
|||
}
|
||||
}
|
||||
|
||||
private void importDatabase(DatabaseImporter.State state) {
|
||||
List<ImportEntry> importEntries = new ArrayList<>();
|
||||
private void processDecryptedImporterState(DatabaseImporter.State state) {
|
||||
DatabaseImporter.Result result;
|
||||
try {
|
||||
result = state.convert();
|
||||
|
@ -206,8 +211,29 @@ public class ImportEntriesActivity extends AegisActivity {
|
|||
return;
|
||||
}
|
||||
|
||||
UUIDMap<VaultEntry> entries = result.getEntries();
|
||||
for (VaultEntry entry : entries.getValues()) {
|
||||
Map<UUID, VaultEntryIcon> icons = result.getEntries().getValues().stream()
|
||||
.filter(e -> e.getIcon() != null
|
||||
&& !e.getIcon().getType().equals(IconType.SVG)
|
||||
&& !BitmapHelper.isVaultEntryIconOptimized(e.getIcon()))
|
||||
.collect(Collectors.toMap(VaultEntry::getUUID, VaultEntry::getIcon));
|
||||
if (!icons.isEmpty()) {
|
||||
IconOptimizationTask task = new IconOptimizationTask(this, newIcons -> {
|
||||
for (Map.Entry<UUID, VaultEntryIcon> mapEntry : newIcons.entrySet()) {
|
||||
VaultEntry entry = result.getEntries().getByUUID(mapEntry.getKey());
|
||||
entry.setIcon(mapEntry.getValue());
|
||||
}
|
||||
|
||||
processImporterResult(result);
|
||||
});
|
||||
task.execute(getLifecycle(), icons);
|
||||
} else {
|
||||
processImporterResult(result);
|
||||
}
|
||||
}
|
||||
|
||||
private void processImporterResult(DatabaseImporter.Result result) {
|
||||
List<ImportEntry> importEntries = new ArrayList<>();
|
||||
for (VaultEntry entry : result.getEntries().getValues()) {
|
||||
ImportEntry importEntry = new ImportEntry(entry);
|
||||
_adapter.addEntry(importEntry);
|
||||
importEntries.add(importEntry);
|
||||
|
|
|
@ -44,9 +44,12 @@ import com.beemdevelopment.aegis.GroupPlaceholderType;
|
|||
import com.beemdevelopment.aegis.Preferences;
|
||||
import com.beemdevelopment.aegis.R;
|
||||
import com.beemdevelopment.aegis.SortCategory;
|
||||
import com.beemdevelopment.aegis.helpers.BitmapHelper;
|
||||
import com.beemdevelopment.aegis.helpers.DropdownHelper;
|
||||
import com.beemdevelopment.aegis.helpers.FabScrollHelper;
|
||||
import com.beemdevelopment.aegis.helpers.PermissionHelper;
|
||||
import com.beemdevelopment.aegis.helpers.ViewHelper;
|
||||
import com.beemdevelopment.aegis.icons.IconType;
|
||||
import com.beemdevelopment.aegis.otp.GoogleAuthInfo;
|
||||
import com.beemdevelopment.aegis.otp.GoogleAuthInfoException;
|
||||
import com.beemdevelopment.aegis.otp.OtpInfoException;
|
||||
|
@ -55,12 +58,13 @@ import com.beemdevelopment.aegis.ui.fragments.preferences.BackupsPreferencesFrag
|
|||
import com.beemdevelopment.aegis.ui.fragments.preferences.PreferencesFragment;
|
||||
import com.beemdevelopment.aegis.ui.models.ErrorCardInfo;
|
||||
import com.beemdevelopment.aegis.ui.models.VaultGroupModel;
|
||||
import com.beemdevelopment.aegis.ui.tasks.IconOptimizationTask;
|
||||
import com.beemdevelopment.aegis.ui.tasks.QrDecodeTask;
|
||||
import com.beemdevelopment.aegis.ui.views.EntryListView;
|
||||
import com.beemdevelopment.aegis.util.TimeUtils;
|
||||
import com.beemdevelopment.aegis.util.UUIDMap;
|
||||
import com.beemdevelopment.aegis.helpers.ViewHelper;
|
||||
import com.beemdevelopment.aegis.vault.VaultEntry;
|
||||
import com.beemdevelopment.aegis.vault.VaultEntryIcon;
|
||||
import com.beemdevelopment.aegis.vault.VaultFile;
|
||||
import com.beemdevelopment.aegis.vault.VaultGroup;
|
||||
import com.beemdevelopment.aegis.vault.VaultRepository;
|
||||
|
@ -724,6 +728,37 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene
|
|||
}
|
||||
}
|
||||
|
||||
private void checkIconOptimization() {
|
||||
if (!_vaultManager.getVault().areIconsOptimized()) {
|
||||
Map<UUID, VaultEntryIcon> oldIcons = _vaultManager.getVault().getEntries().stream()
|
||||
.filter(e -> e.getIcon() != null
|
||||
&& !e.getIcon().getType().equals(IconType.SVG)
|
||||
&& !BitmapHelper.isVaultEntryIconOptimized(e.getIcon()))
|
||||
.collect(Collectors.toMap(VaultEntry::getUUID, VaultEntry::getIcon));
|
||||
|
||||
if (!oldIcons.isEmpty()) {
|
||||
IconOptimizationTask task = new IconOptimizationTask(this, this::onIconsOptimized);
|
||||
task.execute(getLifecycle(), oldIcons);
|
||||
} else {
|
||||
onIconsOptimized(Collections.emptyMap());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void onIconsOptimized(Map<UUID, VaultEntryIcon> newIcons) {
|
||||
for (Map.Entry<UUID, VaultEntryIcon> mapEntry : newIcons.entrySet()) {
|
||||
VaultEntry entry = _vaultManager.getVault().getEntryByUUID(mapEntry.getKey());
|
||||
entry.setIcon(mapEntry.getValue());
|
||||
}
|
||||
|
||||
_vaultManager.getVault().setIconsOptimized(true);
|
||||
saveAndBackupVault();
|
||||
|
||||
if (!newIcons.isEmpty()) {
|
||||
_entryListView.setEntries(_vaultManager.getVault().getEntries());
|
||||
}
|
||||
}
|
||||
|
||||
private void onDecryptResult() {
|
||||
_auditLogRepository.addVaultUnlockedEvent();
|
||||
|
||||
|
@ -912,6 +947,7 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene
|
|||
} else {
|
||||
loadEntries();
|
||||
checkTimeSyncSetting();
|
||||
checkIconOptimization();
|
||||
}
|
||||
|
||||
_lockBackPressHandler.setEnabled(
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
package com.beemdevelopment.aegis.ui.tasks;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
|
||||
import com.beemdevelopment.aegis.R;
|
||||
import com.beemdevelopment.aegis.helpers.BitmapHelper;
|
||||
import com.beemdevelopment.aegis.icons.IconType;
|
||||
import com.beemdevelopment.aegis.vault.VaultEntryIcon;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class IconOptimizationTask extends ProgressDialogTask<Map<UUID, VaultEntryIcon>, Map<UUID, VaultEntryIcon>> {
|
||||
private final Callback _cb;
|
||||
|
||||
public IconOptimizationTask(Context context, Callback cb) {
|
||||
super(context, context.getString(R.string.optimizing_icon));
|
||||
_cb = cb;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<UUID, VaultEntryIcon> doInBackground(Map<UUID, VaultEntryIcon>... params) {
|
||||
Map<UUID, VaultEntryIcon> res = new HashMap<>();
|
||||
Context context = getDialog().getContext();
|
||||
|
||||
int i = 0;
|
||||
Map<UUID, VaultEntryIcon> icons = params[0];
|
||||
for (Map.Entry<UUID, VaultEntryIcon> entry : icons.entrySet()) {
|
||||
if (icons.size() > 1) {
|
||||
publishProgress(context.getString(R.string.optimizing_icon_multiple, i + 1, icons.size()));
|
||||
}
|
||||
i++;
|
||||
|
||||
VaultEntryIcon oldIcon = entry.getValue();
|
||||
if (oldIcon == null || oldIcon.getType().equals(IconType.SVG)) {
|
||||
continue;
|
||||
}
|
||||
if (BitmapHelper.isVaultEntryIconOptimized(oldIcon)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Bitmap bitmap = BitmapFactory.decodeByteArray(oldIcon.getBytes(), 0, oldIcon.getBytes().length);
|
||||
VaultEntryIcon newIcon = BitmapHelper.toVaultEntryIcon(bitmap, oldIcon.getType());
|
||||
bitmap.recycle();
|
||||
res.put(entry.getKey(), newIcon);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Map<UUID, VaultEntryIcon> results) {
|
||||
super.onPostExecute(results);
|
||||
_cb.onTaskFinished(results);
|
||||
}
|
||||
|
||||
public interface Callback {
|
||||
void onTaskFinished(Map<UUID, VaultEntryIcon> results);
|
||||
}
|
||||
}
|
|
@ -15,6 +15,7 @@ public class Vault {
|
|||
private static final int VERSION = 3;
|
||||
private final UUIDMap<VaultEntry> _entries = new UUIDMap<>();
|
||||
private final UUIDMap<VaultGroup> _groups = new UUIDMap<>();
|
||||
private boolean _iconsOptimized = true;
|
||||
|
||||
// Whether we've migrated the group list to the new format while parsing the vault
|
||||
private boolean _isGroupsMigrationFresh = false;
|
||||
|
@ -42,6 +43,7 @@ public class Vault {
|
|||
obj.put("version", VERSION);
|
||||
obj.put("entries", entriesArray);
|
||||
obj.put("groups", groupsArray);
|
||||
obj.put("icons_optimized", _iconsOptimized);
|
||||
|
||||
return obj;
|
||||
} catch (JSONException e) {
|
||||
|
@ -86,6 +88,10 @@ public class Vault {
|
|||
|
||||
entries.add(entry);
|
||||
}
|
||||
|
||||
if (!obj.optBoolean("icons_optimized")) {
|
||||
vault.setIconsOptimized(false);
|
||||
}
|
||||
} catch (VaultEntryException | JSONException e) {
|
||||
throw new VaultException(e);
|
||||
}
|
||||
|
@ -101,6 +107,14 @@ public class Vault {
|
|||
return _isGroupsMigrationFresh;
|
||||
}
|
||||
|
||||
public void setIconsOptimized(boolean optimized) {
|
||||
_iconsOptimized = optimized;
|
||||
}
|
||||
|
||||
public boolean areIconsOptimized() {
|
||||
return _iconsOptimized;
|
||||
}
|
||||
|
||||
public boolean migrateOldGroup(VaultEntry entry) {
|
||||
if (entry.getOldGroup() != null) {
|
||||
Optional<VaultGroup> optGroup = getGroups().getValues()
|
||||
|
|
|
@ -103,8 +103,14 @@ public class VaultEntry extends UUIDMap.Value {
|
|||
entry.setOldGroup(JsonUtils.optString(obj, "group"));
|
||||
}
|
||||
|
||||
VaultEntryIcon icon = VaultEntryIcon.fromJson(obj);
|
||||
entry.setIcon(icon);
|
||||
// Silently ignore any errors that occur when trying to parse the icon of an
|
||||
// entry. This allows us to introduce new icon types in the future (e.g. WebP)
|
||||
// without breaking compatibility with older versions of Aegis.
|
||||
try {
|
||||
VaultEntryIcon icon = VaultEntryIcon.fromJson(obj);
|
||||
entry.setIcon(icon);
|
||||
} catch (VaultEntryIconException ignored) {
|
||||
}
|
||||
|
||||
return entry;
|
||||
} catch (OtpInfoException | JSONException e) {
|
||||
|
|
|
@ -23,6 +23,8 @@ public class VaultEntryIcon implements Serializable {
|
|||
private final byte[] _hash;
|
||||
private final IconType _type;
|
||||
|
||||
public static final int MAX_DIMENS = 512;
|
||||
|
||||
public VaultEntryIcon(byte @NonNull [] bytes, @NonNull IconType type) {
|
||||
this(bytes, type, generateHash(bytes, type));
|
||||
}
|
||||
|
@ -70,7 +72,7 @@ public class VaultEntryIcon implements Serializable {
|
|||
}
|
||||
|
||||
@Nullable
|
||||
static VaultEntryIcon fromJson(@NonNull JSONObject obj) throws VaultEntryException {
|
||||
static VaultEntryIcon fromJson(@NonNull JSONObject obj) throws VaultEntryIconException {
|
||||
try {
|
||||
Object icon = obj.get("icon");
|
||||
if (icon == JSONObject.NULL) {
|
||||
|
@ -80,7 +82,7 @@ public class VaultEntryIcon implements Serializable {
|
|||
String mime = JsonUtils.optString(obj, "icon_mime");
|
||||
IconType iconType = mime == null ? IconType.JPEG : IconType.fromMimeType(mime);
|
||||
if (iconType == IconType.INVALID) {
|
||||
throw new VaultEntryException(String.format("Bad icon MIME type: %s", mime));
|
||||
throw new VaultEntryIconException(String.format("Bad icon MIME type: %s", mime));
|
||||
}
|
||||
|
||||
byte[] iconBytes = Base64.decode((String) icon);
|
||||
|
@ -92,7 +94,7 @@ public class VaultEntryIcon implements Serializable {
|
|||
|
||||
return new VaultEntryIcon(iconBytes, iconType);
|
||||
} catch (JSONException | EncodingException e) {
|
||||
throw new VaultEntryException(e);
|
||||
throw new VaultEntryIconException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
package com.beemdevelopment.aegis.vault;
|
||||
|
||||
public class VaultEntryIconException extends Exception {
|
||||
public VaultEntryIconException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public VaultEntryIconException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
|
@ -333,6 +333,14 @@ public class VaultRepository {
|
|||
return _vault.isGroupsMigrationFresh();
|
||||
}
|
||||
|
||||
public boolean areIconsOptimized() {
|
||||
return _vault.areIconsOptimized();
|
||||
}
|
||||
|
||||
public void setIconsOptimized(boolean optimized) {
|
||||
_vault.setIconsOptimized(optimized);
|
||||
}
|
||||
|
||||
public VaultFileCredentials getCredentials() {
|
||||
return _creds == null ? null : _creds.clone();
|
||||
}
|
||||
|
|
|
@ -236,6 +236,8 @@
|
|||
<string name="snackbar_authentication_method">Please select an authentication method</string>
|
||||
<string name="encrypting_vault">Encrypting the vault</string>
|
||||
<string name="exporting_vault">Exporting the vault</string>
|
||||
<string name="optimizing_icon">Optimizing icon</string>
|
||||
<string name="optimizing_icon_multiple">Optimizing icons %1$d/%2$d</string>
|
||||
<string name="reading_file">Reading file</string>
|
||||
<string name="requesting_root_access">Requesting root access</string>
|
||||
<string name="analyzing_qr">Analyzing QR code</string>
|
||||
|
|
Loading…
Add table
Reference in a new issue