Skip to content

Commit

Permalink
Cleanup the OSS generation and display
Browse files Browse the repository at this point in the history
  • Loading branch information
xgouchet committed Jan 26, 2021
1 parent db2ae3a commit 1a90b4b
Show file tree
Hide file tree
Showing 9 changed files with 191 additions and 134 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,12 @@ import org.w3c.dom.NodeList
* Created by Ekrem HATİPOĞLU on 11.10.2020.
*/


object ManifestType {
const val APPLICATION = "application"
const val INTENT_FILTER = "intent-filter"
const val ATTRS = "attrs"
}


data class AndroidManifest(val items: List<Item>)
data class Item(val tagName: String, val attrs: Map<String, String>, val childList: List<Item> = listOf())

Expand All @@ -42,7 +40,7 @@ fun List<Item>.formatItem(): List<Map<String, Map<String, String>>> {

forEach { intentFilter ->
val item = mutableMapOf<String, Map<String, String>>()
if (intentFilter.attrs.isNotEmpty()){
if (intentFilter.attrs.isNotEmpty()) {
item[ATTRS] = intentFilter.attrs
}

Expand All @@ -55,7 +53,6 @@ fun List<Item>.formatItem(): List<Map<String, Map<String, String>>> {
return list
}


fun Item.getItemsFromChildByType(type: String): List<Item> {
return childList.filter { it.tagName == type }
}
Expand Down Expand Up @@ -101,5 +98,3 @@ private fun NodeList.takeFirst(block: Node.() -> Unit) {
if (this.length > 0)
this.item(0).block()
}


Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ fun exportManifestFromPackage(
}

fun exportManifestDomFromPackage(
info: PackageInfo
info: PackageInfo
): Document {
return parseManifestFile(getPackageApk(info))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,38 @@ package fr.xgouchet.packageexplorer.details

import android.content.ComponentName
import android.content.Context
import android.content.pm.*
import android.content.pm.ApplicationInfo
import android.content.pm.FeatureInfo
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.content.pm.Signature
import android.graphics.drawable.Drawable
import android.os.Build
import fr.xgouchet.packageexplorer.R
import fr.xgouchet.packageexplorer.core.utils.*
import fr.xgouchet.packageexplorer.details.adapter.*
import fr.xgouchet.packageexplorer.core.utils.AndroidManifest
import fr.xgouchet.packageexplorer.core.utils.ManifestType
import fr.xgouchet.packageexplorer.core.utils.filterByName
import fr.xgouchet.packageexplorer.core.utils.formatItem
import fr.xgouchet.packageexplorer.core.utils.getItemsFromChildByType
import fr.xgouchet.packageexplorer.core.utils.humanReadableName
import fr.xgouchet.packageexplorer.details.adapter.AppInfoBullet
import fr.xgouchet.packageexplorer.details.adapter.AppInfoHeader
import fr.xgouchet.packageexplorer.details.adapter.AppInfoSimple
import fr.xgouchet.packageexplorer.details.adapter.AppInfoSubHeader
import fr.xgouchet.packageexplorer.details.adapter.AppInfoType
import fr.xgouchet.packageexplorer.details.adapter.AppInfoViewModel
import fr.xgouchet.packageexplorer.details.adapter.AppInfoWithIcon
import fr.xgouchet.packageexplorer.details.adapter.AppInfoWithSubtitle
import fr.xgouchet.packageexplorer.details.adapter.AppInfoWithSubtitleAndAction
import fr.xgouchet.packageexplorer.details.adapter.AppInfoWithSubtitleAndIcon
import io.reactivex.ObservableEmitter
import timber.log.Timber
import java.io.File
import java.security.MessageDigest
import java.util.zip.ZipEntry
import java.util.zip.ZipInputStream
import javax.security.cert.CertificateException
import javax.security.cert.X509Certificate
import timber.log.Timber

open class DetailsSource(val context: Context) {

Expand All @@ -30,10 +48,10 @@ open class DetailsSource(val context: Context) {
protected var androidManifestXml: AndroidManifest? = null

protected fun extractMainInfo(
emitter: ObservableEmitter<AppInfoViewModel>,
packageInfo: PackageInfo,
applicationInfo: ApplicationInfo?,
apkFile: File?
emitter: ObservableEmitter<AppInfoViewModel>,
packageInfo: PackageInfo,
applicationInfo: ApplicationInfo?,
apkFile: File?
) {
emitter.apply {
onNext(AppInfoWithSubtitle(AppInfoType.INFO_TYPE_METADATA, PACKAGE_NAME, packageInfo.packageName))
Expand Down Expand Up @@ -92,9 +110,9 @@ open class DetailsSource(val context: Context) {
}

protected fun extractActivities(
emitter: ObservableEmitter<AppInfoViewModel>,
packageInfo: PackageInfo,
packageManager: PackageManager
emitter: ObservableEmitter<AppInfoViewModel>,
packageInfo: PackageInfo,
packageManager: PackageManager
) {
val activities = packageInfo.activities ?: return
val packageName = packageInfo.packageName
Expand All @@ -115,14 +133,13 @@ open class DetailsSource(val context: Context) {
onNext(AppInfoWithSubtitleAndIcon(AppInfoType.INFO_TYPE_ACTIVITIES, label, name, activity.name, icon))

extractIntentFilters(this, AppInfoType.INFO_TYPE_ACTIVITIES, activity.name)

}
}
}

protected fun extractServices(
emitter: ObservableEmitter<AppInfoViewModel>,
packageInfo: PackageInfo
emitter: ObservableEmitter<AppInfoViewModel>,
packageInfo: PackageInfo
) {
val services = packageInfo.services ?: return
val packageName = packageInfo.packageName
Expand All @@ -135,14 +152,13 @@ open class DetailsSource(val context: Context) {
onNext(AppInfoSimple(AppInfoType.INFO_TYPE_SERVICES, simplifiedName, service.name))

extractIntentFilters(this, AppInfoType.INFO_TYPE_SERVICES, service.name)

}
}
}

protected fun extractProviders(
emitter: ObservableEmitter<AppInfoViewModel>,
packageInfo: PackageInfo
emitter: ObservableEmitter<AppInfoViewModel>,
packageInfo: PackageInfo
) {
val providers = packageInfo.providers ?: return
val packageName = packageInfo.packageName
Expand All @@ -158,8 +174,8 @@ open class DetailsSource(val context: Context) {
}

protected fun extractReceivers(
emitter: ObservableEmitter<AppInfoViewModel>,
packageInfo: PackageInfo
emitter: ObservableEmitter<AppInfoViewModel>,
packageInfo: PackageInfo
) {
val receivers = packageInfo.receivers ?: return
val packageName = packageInfo.packageName
Expand All @@ -177,8 +193,8 @@ open class DetailsSource(val context: Context) {
}

protected fun extractCustomPermissions(
emitter: ObservableEmitter<AppInfoViewModel>,
packageInfo: PackageInfo
emitter: ObservableEmitter<AppInfoViewModel>,
packageInfo: PackageInfo
) {

val permissions = packageInfo.permissions ?: return
Expand All @@ -201,8 +217,8 @@ open class DetailsSource(val context: Context) {
}

protected fun extractPermissions(
emitter: ObservableEmitter<AppInfoViewModel>,
packageInfo: PackageInfo
emitter: ObservableEmitter<AppInfoViewModel>,
packageInfo: PackageInfo
) {
val permissions = packageInfo.requestedPermissions ?: return
val customPermissions = packageInfo.permissions?.toList()?.map { it.name } ?: emptyList()
Expand Down Expand Up @@ -239,8 +255,8 @@ open class DetailsSource(val context: Context) {
}

protected fun extractFeatures(
emitter: ObservableEmitter<AppInfoViewModel>,
packageInfo: PackageInfo
emitter: ObservableEmitter<AppInfoViewModel>,
packageInfo: PackageInfo
) {
val features = packageInfo.reqFeatures ?: return

Expand Down Expand Up @@ -272,8 +288,8 @@ open class DetailsSource(val context: Context) {
}

protected fun extractSignatures(
emitter: ObservableEmitter<AppInfoViewModel>,
packageInfo: PackageInfo
emitter: ObservableEmitter<AppInfoViewModel>,
packageInfo: PackageInfo
) {
val signatures: Array<Signature> = packageInfo.signatures ?: return
if (signatures.isEmpty()) return
Expand Down Expand Up @@ -301,7 +317,7 @@ open class DetailsSource(val context: Context) {
private fun extractIntentFilters(observableEmitter: ObservableEmitter<AppInfoViewModel>, infoType: Int, name: String) {
androidManifestXml?.let { manifest ->
val parent = manifest.filterByName(name)
val intentFilters= parent.getItemsFromChildByType(ManifestType.INTENT_FILTER)
val intentFilters = parent.getItemsFromChildByType(ManifestType.INTENT_FILTER)

intentFilters.formatItem().forEach { intentFilter ->
observableEmitter.onNext(AppInfoSubHeader(infoType, ManifestType.INTENT_FILTER))
Expand Down Expand Up @@ -363,8 +379,4 @@ open class DetailsSource(val context: Context) {
"${HEX_CHARS[firstIndex]}${HEX_CHARS[secondIndex]}"
}
}

}



Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ class AppInfoHeaderViewHolder(
}

class AppInfoSubHeaderViewHolder(
itemView: View,
listener: BiConsumer<AppInfoViewModel, View?>?
itemView: View,
listener: BiConsumer<AppInfoViewModel, View?>?
) : AppInfoViewHolder<AppInfoSubHeader>(itemView, listener) {

private val titleView: TextView = itemView.findViewById(R.id.title)
Expand All @@ -76,8 +76,8 @@ class AppInfoSimpleViewHolder(
}

class AppInfoBulletViewHolder(
itemView: View,
listener: BiConsumer<AppInfoViewModel, View?>?
itemView: View,
listener: BiConsumer<AppInfoViewModel, View?>?
) : AppInfoViewHolder<AppInfoBullet>(itemView, listener) {

private val iconView: ImageView = itemView.findViewById(R.id.icon)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,14 @@ interface AppInfoSelectable {
}

data class AppInfoSubHeader(
val type: Int,
val header: String
val type: Int,
val header: String
) : AppInfoViewModel(type, "SubHeader {$type} “$header")


data class AppInfoSimple(
val type: Int,
val title: String,
val raw: String? = null
val type: Int,
val title: String,
val raw: String? = null
) :
AppInfoViewModel(type, "Simple {$type} “$title"),
AppInfoSelectable {
Expand All @@ -61,12 +60,12 @@ data class AppInfoSimple(
}

data class AppInfoBullet(
val type: Int,
val name: String,
val value: String,
val raw: String? = null,
val separator: String = "=",
@DrawableRes val icon: Int = R.drawable.ic_bullet
val type: Int,
val name: String,
val value: String,
val raw: String? = null,
val separator: String = "=",
@DrawableRes val icon: Int = R.drawable.ic_bullet

) :
AppInfoViewModel(type, "Bullet {$type} “$value"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import io.reactivex.ObservableOnSubscribe
import java.io.IOException

class OSSDependenciesSource(val context: Context) :
ObservableOnSubscribe<AppInfoViewModel> {
ObservableOnSubscribe<AppInfoViewModel> {

override fun subscribe(emitter: ObservableEmitter<AppInfoViewModel>) {

Expand All @@ -23,29 +23,61 @@ class OSSDependenciesSource(val context: Context) :
val gson: Gson = GsonBuilder().create()

val data = gson.fromJson(
stream.reader(Charsets.UTF_8),
Array<OSSDependency>::class.java
stream.reader(Charsets.UTF_8),
Array<OSSDependency>::class.java
).sortedBy { it.identifier }

val androidX = data.filter { it.identifier.startsWith("androidx") }
val kotlin = data.filter { it.identifier.startsWith("org.jetbrains.kotlin") }
val misc = data.filter {
(!it.identifier.startsWith("org.jetbrains.kotlin")) &&
(!it.identifier.startsWith("androidx"))
(!it.identifier.startsWith("androidx"))
}

if (androidX.isNotEmpty()) {
emitter.onNext(AppInfoHeader(AppInfoType.INFO_TYPE_ANDROID, "AndroidX", R.drawable.ic_oss_android_logo))
androidX.forEach { emitter.onNext(convertDependency(it, AppInfoType.INFO_TYPE_ANDROID)) }
emitter.onNext(
AppInfoHeader(
AppInfoType.INFO_TYPE_ANDROID,
"AndroidX",
R.drawable.ic_oss_android_logo
)
)
androidX.forEach {
emitter.onNext(
convertDependency(
it,
AppInfoType.INFO_TYPE_ANDROID
)
)
}
}

if (kotlin.isNotEmpty()) {
emitter.onNext(AppInfoHeader(AppInfoType.INFO_TYPE_KOTLIN, "Kotlin", R.drawable.ic_oss_kotlin_logo))
kotlin.forEach { emitter.onNext(convertDependency(it, AppInfoType.INFO_TYPE_KOTLIN)) }
emitter.onNext(
AppInfoHeader(
AppInfoType.INFO_TYPE_KOTLIN,
"Kotlin",
R.drawable.ic_oss_kotlin_logo
)
)
kotlin.forEach {
emitter.onNext(
convertDependency(
it,
AppInfoType.INFO_TYPE_KOTLIN
)
)
}
}

if (misc.isNotEmpty()) {
emitter.onNext(AppInfoHeader(AppInfoType.INFO_TYPE_MISC, "Misc", R.drawable.ic_oss_package_logo))
emitter.onNext(
AppInfoHeader(
AppInfoType.INFO_TYPE_MISC,
"Misc",
R.drawable.ic_oss_package_logo
)
)
misc.forEach { emitter.onNext(convertDependency(it, AppInfoType.INFO_TYPE_MISC)) }
}

Expand All @@ -55,22 +87,14 @@ class OSSDependenciesSource(val context: Context) :
}

private fun convertDependency(ossDependency: OSSDependency, type: Int): AppInfoViewModel {
return if (ossDependency.sourceUrl.isNullOrBlank()) {
AppInfoWithSubtitle(
type,
ossDependency.name,
"${ossDependency.identifier}\n${ossDependency.license}",
ossDependency.identifier
)
val title = "${ossDependency.name}${ossDependency.licenseKey}"
val subtitle = "${ossDependency.identifier}\n${ossDependency.license}"
val raw = ossDependency.identifier
val actionData = ossDependency.sourceUrl
return if (actionData.isNullOrBlank()) {
AppInfoWithSubtitle(type, title, subtitle, raw)
} else {
AppInfoWithSubtitleAndAction(
type,
ossDependency.name,
"${ossDependency.identifier}\n${ossDependency.license}",
ossDependency.identifier,
"Source",
ossDependency.sourceUrl
)
AppInfoWithSubtitleAndAction(type, title, subtitle, raw, "Source", actionData)
}
}
}
Loading

0 comments on commit 1a90b4b

Please sign in to comment.