diff options
Diffstat (limited to 'app/src/main/java/moe/yuuta/workmode/suspend/data')
3 files changed, 162 insertions, 18 deletions
diff --git a/app/src/main/java/moe/yuuta/workmode/suspend/data/PersistableSuspendedApp.kt b/app/src/main/java/moe/yuuta/workmode/suspend/data/PersistableSuspendedApp.kt new file mode 100644 index 0000000..ccfc008 --- /dev/null +++ b/app/src/main/java/moe/yuuta/workmode/suspend/data/PersistableSuspendedApp.kt @@ -0,0 +1,41 @@ +package moe.yuuta.workmode.suspend.data + +import android.os.Process +import java.util.regex.Pattern + +/** + * The data of Suspended app which can be stored in {@link SuspendedStorage} only + */ +data class PersistableSuspendedApp( + val userId: Int, + val packageName: String +) { + constructor(serializedString: String) : this(parseUserIDFromSerializedString(serializedString), + parsePackageNameFromSerializedString(serializedString)) + + override fun toString(): String = + String.format("%d|%s", userId, packageName) + + /** + * Create a TransferableSuspendedApp with the simplest data. + */ + fun copyToSimpleTransferableInfo(): TransferableSuspendedApp = + TransferableSuspendedApp(userId, packageName, null, -1, null) + + companion object { + private fun parseFromSerializedString(serializedString: String): PersistableSuspendedApp { + val arr = serializedString.split(Pattern.compile("\\|")) + // Legacy + if (arr.size != 2) { + return PersistableSuspendedApp(Process.myUserHandle().hashCode(), serializedString) + } + return PersistableSuspendedApp(arr[0].toInt(), arr[1]) + } + + private fun parseUserIDFromSerializedString(serializedString: String): Int = + parseFromSerializedString(serializedString).userId + + private fun parsePackageNameFromSerializedString(serializedString: String): String = + parseFromSerializedString(serializedString).packageName + } +}
\ No newline at end of file diff --git a/app/src/main/java/moe/yuuta/workmode/suspend/data/SuspendedStorage.kt b/app/src/main/java/moe/yuuta/workmode/suspend/data/SuspendedStorage.kt index 74c9b67..af3cd87 100644 --- a/app/src/main/java/moe/yuuta/workmode/suspend/data/SuspendedStorage.kt +++ b/app/src/main/java/moe/yuuta/workmode/suspend/data/SuspendedStorage.kt @@ -7,7 +7,6 @@ import com.crashlytics.android.answers.Answers import com.crashlytics.android.answers.CustomEvent import com.elvishew.xlog.XLog import moe.yuuta.workmode.Setup -import moe.yuuta.workmode.utils.Utils import java.util.stream.Collectors /** @@ -31,9 +30,27 @@ class SuspendedStorage(mContext: Context) { fun getStorage(): SharedPreferences = storage - fun getList(): List<String> = (getStorage().getStringSet("list", setOf()) ?: listOf<String>()).toList() + fun getList(): List<PersistableSuspendedApp> = + _getList().stream() + .map { + return@map PersistableSuspendedApp(it) + } + .collect(Collectors.toList()) - fun setList(set: Set<String>) { + fun setList(set: Set<PersistableSuspendedApp>) { + _setList(set.stream() + .map { + return@map it.toString() + } + .collect(Collectors.toSet())) + } + + /** + * Internal get list (string) + */ + private fun _getList(): List<String> = (getStorage().getStringSet("list", setOf()) ?: listOf<String>()).toList() + + private fun _setList(set: Set<String>) { logger.d("s() $set") getStorage().edit().putStringSet("list", set).apply() } @@ -68,21 +85,6 @@ class SuspendedStorage(mContext: Context) { else -> ListMode.BLACKLIST } - fun cleanList(context: Context) { - val installed = context.packageManager.getInstalledApplications(0) - .stream() - .filter(Utils.buildGeneralApplicationInfoFilter(context)) - .map { - return@map it.packageName - } - .collect(Collectors.toList()) - setList(getList().stream() - .filter { - return@filter installed.contains(it) - } - .collect(Collectors.toSet())) - } - // #Anti-Crack fun reportCrack(id: String, reason: String) { if (getList().isEmpty()) { diff --git a/app/src/main/java/moe/yuuta/workmode/suspend/data/TransferableSuspendedApp.kt b/app/src/main/java/moe/yuuta/workmode/suspend/data/TransferableSuspendedApp.kt new file mode 100644 index 0000000..03bf842 --- /dev/null +++ b/app/src/main/java/moe/yuuta/workmode/suspend/data/TransferableSuspendedApp.kt @@ -0,0 +1,101 @@ +package moe.yuuta.workmode.suspend.data + +import android.annotation.SystemApi +import android.content.pm.PackageManager +import android.graphics.Bitmap +import android.graphics.BitmapFactory +import android.os.Parcel +import android.os.Parcelable +import android.os.Process +import android.text.TextUtils +import com.elvishew.xlog.XLog + +/** + * The data of Suspended app which can be transfered through IPC only + */ +data class TransferableSuspendedApp( + val userId: Int, + val packageName: String, + // Null if it has the same user id with the host + var label: CharSequence?, + // -1 if not available + var uid: Int, + // Null if it has the same user id with the host + var icon: Bitmap? +) : Parcelable { + constructor(parcel: Parcel) : this( + parcel.readInt(), + parcel.readString(), + TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel), + parcel.readInt(), + parcel.readParcelable<Bitmap>(Bitmap::class.java.classLoader) + ) + + fun trimToPersistable(): PersistableSuspendedApp = + PersistableSuspendedApp(userId, packageName) + + /** + * Fill all fields. + */ + @SystemApi + fun fillData(pm: PackageManager, ignoreLargeData: Boolean) { + val info = pm.getApplicationInfoAsUser(packageName, + 0, + userId) + label = if (ignoreLargeData) null + else pm.getApplicationLabel(info) + uid = info.uid + if (ignoreLargeData) { + icon = null + } else { + XLog.d("Loading icon for ${info.packageName}") + val res = pm.getResourcesForApplicationAsUser(info.packageName, userId) + icon = BitmapFactory.decodeResource(res, info.icon) + } + } + + /** + * Remove unnecessary data for in-app transaction + */ + fun trimData() { + label = null + uid = -1 + icon = null + } + + companion object { + fun of(packageName: String): TransferableSuspendedApp { + return of(packageName, Process.myUserHandle().hashCode()) + } + + fun of(packageName: String, userId: Int): TransferableSuspendedApp { + return PersistableSuspendedApp(userId, packageName).copyToSimpleTransferableInfo() + } + + @JvmField + val CREATOR = object : Parcelable.Creator<TransferableSuspendedApp> { + override fun createFromParcel(parcel: Parcel): TransferableSuspendedApp { + return TransferableSuspendedApp(parcel) + } + + override fun newArray(size: Int): Array<TransferableSuspendedApp?> { + return arrayOfNulls(size) + } + } + } + + override fun writeToParcel(parcel: Parcel, flags: Int) { + parcel.writeInt(userId) + parcel.writeString(packageName) + TextUtils.writeToParcel(label, parcel, flags) + parcel.writeInt(uid) + parcel.writeParcelable(icon, 0) + } + + override fun describeContents(): Int { + return 0 + } + + fun essentiallyEqual(that: TransferableSuspendedApp): Boolean = that.userId == this.userId && + that.packageName == this.packageName +}
\ No newline at end of file |