APK反编译源代码展示 - 南明离火平台提供

应用版本信息
应用名称:SERVER HACKER
版本号:1.0
包名称:com.android.serverhackram

MD5 校验值:ecd580f5871ea641118d82ebcc32ef4d

反编译源代码说明

DatabasePersistence.java 文件包含反编译后的源代码,请注意,该内容仅供学习和参考使用,不得用于非法用途。


package com.microsoft.appcenter.persistence;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteFullException;
import android.database.sqlite.SQLiteQueryBuilder;
import com.microsoft.appcenter.Constants;
import com.microsoft.appcenter.Flags;
import com.microsoft.appcenter.ingestion.models.Log;
import com.microsoft.appcenter.ingestion.models.one.CommonSchemaLog;
import com.microsoft.appcenter.ingestion.models.one.PartAUtils;
import com.microsoft.appcenter.persistence.Persistence;
import com.microsoft.appcenter.utils.AppCenterLog;
import com.microsoft.appcenter.utils.crypto.CryptoUtils;
import com.microsoft.appcenter.utils.storage.DatabaseManager;
import com.microsoft.appcenter.utils.storage.FileManager;
import com.microsoft.appcenter.utils.storage.SQLiteUtils;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import org.json.JSONException;

public class DatabasePersistence extends Persistence {
    private static final String COLUMN_DATA_TYPE = "type";
    static final String COLUMN_GROUP = "persistence_group";
    static final String COLUMN_LOG = "log";
    static final String COLUMN_PRIORITY = "priority";
    static final String COLUMN_TARGET_KEY = "target_key";
    static final String COLUMN_TARGET_TOKEN = "target_token";
    static final String CREATE_LOGS_SQL = "CREATE TABLE IF NOT EXISTS `logs`(`oid` INTEGER PRIMARY KEY AUTOINCREMENT,`target_token` TEXT,`type` TEXT,`priority` INTEGER,`log` TEXT,`persistence_group` TEXT,`target_key` TEXT);";
    private static final String CREATE_PRIORITY_INDEX_LOGS = "CREATE INDEX `ix_logs_priority` ON logs (`priority`)";
    static final String DATABASE = "com.microsoft.appcenter.persistence";
    private static final String DROP_LOGS_SQL = "DROP TABLE `logs`";
    private static final String GET_SORT_ORDER = "priority DESC, oid";
    private static final String PAYLOAD_FILE_EXTENSION = ".json";
    private static final String PAYLOAD_LARGE_DIRECTORY = "/appcenter/database_large_payloads";
    static final int PAYLOAD_MAX_SIZE = 1992294;
    static final ContentValues SCHEMA = getContentValues("", "", "", "", "", 0);
    static final String TABLE = "logs";
    private static final int VERSION = 6;
    static final int VERSION_TIMESTAMP_COLUMN = 5;
    private final Context mContext;
    final DatabaseManager mDatabaseManager;
    private final File mLargePayloadDirectory;
    private long mLargePayloadsSize;
    final Set<Long> mPendingDbIdentifiers;
    final Map<String, List<Long>> mPendingDbIdentifiersGroups;

    public DatabasePersistence(Context context) {
        this(context, 6, SCHEMA);
    }

    DatabasePersistence(Context context, int version, final ContentValues schema) {
        this.mContext = context;
        this.mPendingDbIdentifiersGroups = new HashMap();
        this.mPendingDbIdentifiers = new HashSet();
        this.mDatabaseManager = new DatabaseManager(context, DATABASE, TABLE, version, schema, CREATE_LOGS_SQL, new DatabaseManager.Listener() {
            @Override
            public void onCreate(SQLiteDatabase db) {
                db.execSQL(DatabasePersistence.CREATE_PRIORITY_INDEX_LOGS);
            }

            @Override
            public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
                db.execSQL(DatabasePersistence.DROP_LOGS_SQL);
                db.execSQL(DatabasePersistence.CREATE_LOGS_SQL);
                db.execSQL(DatabasePersistence.CREATE_PRIORITY_INDEX_LOGS);
            }
        });
        File file = new File(Constants.FILES_PATH + PAYLOAD_LARGE_DIRECTORY);
        this.mLargePayloadDirectory = file;
        file.mkdirs();
        this.mLargePayloadsSize = checkLargePayloadFilesAndCollectTheirSize();
    }

    private static ContentValues getContentValues(String group, String logJ, String targetToken, String type, String targetKey, int priority) {
        ContentValues contentValues = new ContentValues();
        contentValues.put(COLUMN_GROUP, group);
        contentValues.put(COLUMN_LOG, logJ);
        contentValues.put(COLUMN_TARGET_TOKEN, targetToken);
        contentValues.put("type", type);
        contentValues.put(COLUMN_TARGET_KEY, targetKey);
        contentValues.put("priority", Integer.valueOf(priority));
        return contentValues;
    }

    @Override
    public boolean setMaxStorageSize(long maxStorageSizeInBytes) {
        boolean maxSize = this.mDatabaseManager.setMaxSize(maxStorageSizeInBytes);
        deleteLogsThatNotFitMaxSize();
        return maxSize;
    }

    @Override
    public long putLog(Log log, String group, int flags) throws Persistence.PersistenceException {
        String str;
        String str2;
        try {
            try {
                AppCenterLog.debug("AppCenter", "Storing a log to the Persistence database for log type " + log.getType() + " with flags=" + flags);
                String serializeLog = getLogSerializer().serializeLog(log);
                int length = serializeLog.getBytes("UTF-8").length;
                boolean z = length >= PAYLOAD_MAX_SIZE;
                Long l = null;
                if (!(log instanceof CommonSchemaLog)) {
                    str = null;
                    str2 = null;
                } else {
                    if (z) {
                        throw new Persistence.PersistenceException("Log is larger than 1992294 bytes, cannot send to OneCollector.");
                    }
                    String next = log.getTransmissionTargetTokens().iterator().next();
                    String targetKey = PartAUtils.getTargetKey(next);
                    str = CryptoUtils.getInstance(this.mContext).encrypt(next);
                    str2 = targetKey;
                }
                long maxSize = this.mDatabaseManager.getMaxSize();
                if (maxSize == -1) {
                    throw new Persistence.PersistenceException("Failed to store a log to the Persistence database.");
                }
                long j = length;
                if (maxSize <= j) {
                    throw new Persistence.PersistenceException("Log is too large (" + length + " bytes) to store in database. Current maximum database size is " + maxSize + " bytes.");
                }
                int persistenceFlag = Flags.getPersistenceFlag(flags, false);
                long j2 = maxSize;
                try {
                    ContentValues contentValues = getContentValues(group, z ? null : serializeLog, str, log.getType(), str2, persistenceFlag);
                    while (z) {
                        if (getStoredDataSize() + j <= j2) {
                            break;
                        }
                        AppCenterLog.debug("AppCenter", "Storage is full, trying to delete the oldest log that has the lowest priority which is lower or equal priority than the new log.");
                        long j3 = j2;
                        if (deleteTheOldestLog(persistenceFlag) == -1) {
                            throw new Persistence.PersistenceException("Failed to clear space for new log record.");
                        }
                        j2 = j3;
                    }
                    while (l == null) {
                        try {
                            l = Long.valueOf(this.mDatabaseManager.put(contentValues));
                        } catch (SQLiteFullException unused) {
                            AppCenterLog.debug("AppCenter", "Storage is full, trying to delete the oldest log that has the lowest priority which is lower or equal priority than the new log.");
                            if (deleteTheOldestLog(persistenceFlag) == -1) {
                                l = -1L;
                            }
                        }
                    }
                    if (l.longValue() == -1) {
                        throw new Persistence.PersistenceException("Failed to store a log to the Persistence database for log type " + log.getType() + ".");
                    }
                    AppCenterLog.debug("AppCenter", "Stored a log to the Persistence database for log type " + log.getType() + " with databaseId=" + l);
                    if (z) {
                        AppCenterLog.debug("AppCenter", "Payload is larger than what SQLite supports, storing payload in a separate file.");
                        File largePayloadGroupDirectory = getLargePayloadGroupDirectory(group);
                        largePayloadGroupDirectory.mkdir();
                        File largePayloadFile = getLargePayloadFile(largePayloadGroupDirectory, l.longValue());
                        try {
                            FileManager.write(largePayloadFile, serializeLog);
                            this.mLargePayloadsSize += largePayloadFile.length();
                            AppCenterLog.verbose("AppCenter", "Store extra " + largePayloadFile.length() + " KB as a separated payload file.");
                            AppCenterLog.debug("AppCenter", "Payload written to " + largePayloadFile);
                        } catch (IOException e) {
                            this.mDatabaseManager.delete(l.longValue());
                            throw e;
                        }
                    }
                    deleteLogsThatNotFitMaxSize();
                    return l.longValue();
                } catch (IOException e2) {
                    e = e2;
                    throw new Persistence.PersistenceException("Cannot save large payload in a file.", e);
                } catch (JSONException e3) {
                    e = e3;
                    throw new Persistence.PersistenceException("Cannot convert to JSON string.", e);
                }
            } catch (IOException e4) {
                e = e4;
            }
        } catch (JSONException e5) {
            e = e5;
        }
    }

    File getLargePayloadGroupDirectory(String group) {
        return new File(this.mLargePayloadDirectory, group);
    }

    File getLargePayloadFile(File directory, long databaseId) {
        return new File(directory, databaseId + ".json");
    }

    private void deleteLog(File groupLargePayloadDirectory, long id) {
        getLargePayloadFile(groupLargePayloadDirectory, id).delete();
        this.mDatabaseManager.delete(id);
    }

    @Override
    public void deleteLogs(String group, String id) {
        AppCenterLog.debug("AppCenter", "Deleting logs from the Persistence database for " + group + " with " + id);
        AppCenterLog.debug("AppCenter", "The IDs for deleting log(s) is/are:");
        List<Long> remove = this.mPendingDbIdentifiersGroups.remove(group + id);
        File largePayloadGroupDirectory = getLargePayloadGroupDirectory(group);
        if (remove != null) {
            for (Long l : remove) {
                AppCenterLog.debug("AppCenter", "\t" + l);
                deleteLog(largePayloadGroupDirectory, l.longValue());
                this.mPendingDbIdentifiers.remove(l);
            }
        }
    }

    @Override
    public void deleteLogs(String group) {
        AppCenterLog.debug("AppCenter", "Deleting all logs from the Persistence database for " + group);
        File largePayloadGroupDirectory = getLargePayloadGroupDirectory(group);
        File[] listFiles = largePayloadGroupDirectory.listFiles();
        if (listFiles != null) {
            for (File file : listFiles) {
                file.delete();
            }
        }
        largePayloadGroupDirectory.delete();
        AppCenterLog.debug("AppCenter", "Deleted " + this.mDatabaseManager.delete(COLUMN_GROUP, group) + " logs.");
        Iterator<String> it = this.mPendingDbIdentifiersGroups.keySet().iterator();
        while (it.hasNext()) {
            if (it.next().startsWith(group)) {
                it.remove();
            }
        }
    }

    @Override
    public int countLogs(String group) {
        SQLiteQueryBuilder newSQLiteQueryBuilder = SQLiteUtils.newSQLiteQueryBuilder();
        newSQLiteQueryBuilder.appendWhere("persistence_group = ?");
        int i = 0;
        try {
            Cursor cursor = this.mDatabaseManager.getCursor(newSQLiteQueryBuilder, new String[]{"COUNT(*)"}, new String[]{group}, null);
            try {
                cursor.moveToNext();
                i = cursor.getInt(0);
                cursor.close();
            } catch (Throwable th) {
                cursor.close();
                throw th;
            }
        } catch (RuntimeException e) {
            AppCenterLog.error("AppCenter", "Failed to get logs count: ", e);
        }
        return i;
    }

    @Override
    public String getLogs(String group, Collection<String> pausedTargetKeys, int limit, List<Log> outLogs) {
        Cursor cursor;
        AppCenterLog.debug("AppCenter", "Trying to get " + limit + " logs from the Persistence database for " + group);
        SQLiteQueryBuilder newSQLiteQueryBuilder = SQLiteUtils.newSQLiteQueryBuilder();
        newSQLiteQueryBuilder.appendWhere("persistence_group = ?");
        ArrayList arrayList = new ArrayList();
        arrayList.add(group);
        if (!pausedTargetKeys.isEmpty()) {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < pausedTargetKeys.size(); i++) {
                sb.append("?,");
            }
            sb.deleteCharAt(sb.length() - 1);
            newSQLiteQueryBuilder.appendWhere(" AND ");
            newSQLiteQueryBuilder.appendWhere("target_key NOT IN (" + sb.toString() + ")");
            arrayList.addAll(pausedTargetKeys);
        }
        LinkedHashMap linkedHashMap = new LinkedHashMap();
        ArrayList arrayList2 = new ArrayList();
        File largePayloadGroupDirectory = getLargePayloadGroupDirectory(group);
        String[] strArr = (String[]) arrayList.toArray(new String[0]);
        try {
            cursor = this.mDatabaseManager.getCursor(newSQLiteQueryBuilder, null, strArr, GET_SORT_ORDER);
        } catch (RuntimeException e) {
            AppCenterLog.error("AppCenter", "Failed to get logs: ", e);
            cursor = null;
        }
        int i2 = 0;
        while (cursor != null) {
            ContentValues nextValues = this.mDatabaseManager.nextValues(cursor);
            if (nextValues == null || i2 >= limit) {
                break;
            }
            Long asLong = nextValues.getAsLong(DatabaseManager.PRIMARY_KEY);
            if (asLong == null) {
                AppCenterLog.error("AppCenter", "Empty database record, probably content was larger than 2MB, need to delete as it's now corrupted.");
                Iterator<Long> it = getLogsIds(newSQLiteQueryBuilder, strArr).iterator();
                while (true) {
                    if (it.hasNext()) {
                        Long next = it.next();
                        if (!this.mPendingDbIdentifiers.contains(next) && !linkedHashMap.containsKey(next)) {
                            deleteLog(largePayloadGroupDirectory, next.longValue());
                            AppCenterLog.error("AppCenter", "Empty database corrupted empty record deleted, id=" + next);
                            break;
                        }
                    }
                }
            } else if (!this.mPendingDbIdentifiers.contains(asLong)) {
                try {
                    String asString = nextValues.getAsString(COLUMN_LOG);
                    if (asString == null) {
                        File largePayloadFile = getLargePayloadFile(largePayloadGroupDirectory, asLong.longValue());
                        AppCenterLog.debug("AppCenter", "Read payload file " + largePayloadFile);
                        asString = FileManager.read(largePayloadFile);
                        if (asString == null) {
                            throw new JSONException("Log payload is null and not stored as a file.");
                            break;
                        }
                    }
                    Log deserializeLog = getLogSerializer().deserializeLog(asString, nextValues.getAsString("type"));
                    String asString2 = nextValues.getAsString(COLUMN_TARGET_TOKEN);
                    if (asString2 != null) {
                        deserializeLog.addTransmissionTarget(CryptoUtils.getInstance(this.mContext).decrypt(asString2).getDecryptedData());
                    }
                    linkedHashMap.put(asLong, deserializeLog);
                    i2++;
                } catch (JSONException e2) {
                    AppCenterLog.error("AppCenter", "Cannot deserialize a log in the database", e2);
                    arrayList2.add(asLong);
                }
            }
        }
        if (cursor != null) {
            try {
                cursor.close();
            } catch (RuntimeException unused) {
            }
        }
        if (arrayList2.size() > 0) {
            Iterator it2 = arrayList2.iterator();
            while (it2.hasNext()) {
                deleteLog(largePayloadGroupDirectory, ((Long) it2.next()).longValue());
            }
            AppCenterLog.warn("AppCenter", "Deleted logs that cannot be deserialized");
        }
        if (linkedHashMap.size() <= 0) {
            AppCenterLog.debug("AppCenter", "No logs found in the Persistence database at the moment");
            return null;
        }
        String uuid = UUID.randomUUID().toString();
        AppCenterLog.debug("AppCenter", "Returning " + linkedHashMap.size() + " log(s) with an ID, " + uuid);
        AppCenterLog.debug("AppCenter", "The SID/ID pairs for returning log(s) is/are:");
        ArrayList arrayList3 = new ArrayList();
        for (Map.Entry entry : linkedHashMap.entrySet()) {
            Long l = (Long) entry.getKey();
            this.mPendingDbIdentifiers.add(l);
            arrayList3.add(l);
            outLogs.add((Log) entry.getValue());
            AppCenterLog.debug("AppCenter", "\t" + ((Log) entry.getValue()).getSid() + " / " + l);
        }
        this.mPendingDbIdentifiersGroups.put(group + uuid, arrayList3);
        return uuid;
    }

    @Override
    public void clearPendingLogState() {
        this.mPendingDbIdentifiers.clear();
        this.mPendingDbIdentifiersGroups.clear();
        AppCenterLog.debug("AppCenter", "Cleared pending log states");
    }

    @Override
    public void close() {
        this.mDatabaseManager.close();
    }

    public void deleteLogsThatNotFitMaxSize() {
        int persistenceFlag = Flags.getPersistenceFlag(1, false);
        while (getStoredDataSize() >= this.mDatabaseManager.getMaxSize() && deleteTheOldestLog(persistenceFlag) != -1) {
        }
    }

    private long getStoredDataSize() {
        return this.mDatabaseManager.getCurrentSize() + this.mLargePayloadsSize;
    }

    private long deleteTheOldestLog(int priority) {
        HashSet hashSet = new HashSet();
        hashSet.add(DatabaseManager.PRIMARY_KEY);
        hashSet.add(COLUMN_GROUP);
        ContentValues deleteTheOldestRecord = this.mDatabaseManager.deleteTheOldestRecord(hashSet, "priority", priority);
        if (deleteTheOldestRecord == null) {
            return -1L;
        }
        long longValue = deleteTheOldestRecord.getAsLong(DatabaseManager.PRIMARY_KEY).longValue();
        File largePayloadFile = getLargePayloadFile(getLargePayloadGroupDirectory(deleteTheOldestRecord.getAsString(COLUMN_GROUP)), longValue);
        if (!largePayloadFile.exists()) {
            return longValue;
        }
        long length = largePayloadFile.length();
        if (largePayloadFile.delete()) {
            this.mLargePayloadsSize -= length;
            AppCenterLog.verbose("AppCenter", "Large payload file with id " + longValue + " has been deleted. " + length + " KB of memory has been freed.");
        } else {
            AppCenterLog.warn("AppCenter", "Cannot delete large payload file with id " + longValue);
        }
        return longValue;
    }

    private long checkLargePayloadFilesAndCollectTheirSize() {
        FilenameFilter filenameFilter = new FilenameFilter() {
            @Override
            public boolean accept(File file, String fileName) {
                return fileName.endsWith(".json");
            }
        };
        Set<Long> logsIds = getLogsIds(SQLiteUtils.newSQLiteQueryBuilder(), new String[0]);
        File[] listFiles = this.mLargePayloadDirectory.listFiles();
        long j = 0;
        if (listFiles == null) {
            return 0L;
        }
        for (File file : listFiles) {
            File[] listFiles2 = file.listFiles(filenameFilter);
            if (listFiles2 != null) {
                for (File file2 : listFiles2) {
                    try {
                        long parseInt = Integer.parseInt(FileManager.getNameWithoutExtension(file2));
                        if (logsIds.contains(Long.valueOf(parseInt))) {
                            j += file2.length();
                        } else if (file2.delete()) {
                            AppCenterLog.debug("AppCenter", "Lasted large payload file with name " + file2.getName() + " has been deleted.");
                        } else {
                            AppCenterLog.warn("AppCenter", "Cannot delete redundant large payload file with id " + parseInt);
                        }
                    } catch (NumberFormatException unused) {
                        AppCenterLog.warn("AppCenter", "A file was found whose name does not match the pattern of naming log files: " + file2.getName());
                    }
                }
            }
        }
        return j;
    }

    private Set<Long> getLogsIds(SQLiteQueryBuilder builder, String... selectionArgs) {
        HashSet hashSet = new HashSet();
        try {
            Cursor cursor = this.mDatabaseManager.getCursor(builder, DatabaseManager.SELECT_PRIMARY_KEY, selectionArgs, null);
            while (cursor.moveToNext()) {
                try {
                    hashSet.add(this.mDatabaseManager.buildValues(cursor).getAsLong(DatabaseManager.PRIMARY_KEY));
                } catch (Throwable th) {
                    cursor.close();
                    throw th;
                }
            }
            cursor.close();
        } catch (RuntimeException e) {
            AppCenterLog.error("AppCenter", "Failed to get corrupted ids: ", e);
        }
        return hashSet;
    }
}