Commit 617fbc0b authored by CzBiX's avatar CzBiX Committed by Max Lv

Show uid and package name on app list

parent f4bb68d6
...@@ -46,7 +46,9 @@ ...@@ -46,7 +46,9 @@
<string name="proxied_apps">Apps VPN mode</string> <string name="proxied_apps">Apps VPN mode</string>
<string name="proxied_apps_summary">Configure VPN mode for selected apps</string> <string name="proxied_apps_summary">Configure VPN mode for selected apps</string>
<string name="on">On</string> <string name="on">On</string>
<string name="bypass_apps">Bypass Mode</string> <string name="off">Off</string>
<string name="mode">Mode</string>
<string name="bypass_apps">Bypass</string>
<string name="bypass_apps_summary">Enable this option to bypass selected apps</string> <string name="bypass_apps_summary">Enable this option to bypass selected apps</string>
<string name="auto_connect">Auto Connect</string> <string name="auto_connect">Auto Connect</string>
<string name="auto_connect_summary">Enable Shadowsocks on startup</string> <string name="auto_connect_summary">Enable Shadowsocks on startup</string>
......
...@@ -66,6 +66,7 @@ dependencies { ...@@ -66,6 +66,7 @@ dependencies {
testImplementation "junit:junit:$junitVersion" testImplementation "junit:junit:$junitVersion"
androidTestImplementation "androidx.test:runner:$androidTestVersion" androidTestImplementation "androidx.test:runner:$androidTestVersion"
androidTestImplementation "androidx.test.espresso:espresso-core:$androidEspressoVersion" androidTestImplementation "androidx.test.espresso:espresso-core:$androidEspressoVersion"
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
} }
repositories { repositories {
mavenCentral() mavenCentral()
......
...@@ -34,12 +34,15 @@ import android.graphics.drawable.Drawable ...@@ -34,12 +34,15 @@ import android.graphics.drawable.Drawable
import android.os.Bundle import android.os.Bundle
import android.view.* import android.view.*
import android.widget.ImageView import android.widget.ImageView
import android.widget.RadioButton
import android.widget.Switch import android.widget.Switch
import android.widget.TextView
import androidx.annotation.UiThread import androidx.annotation.UiThread
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.core.content.getSystemService import androidx.core.content.getSystemService
import androidx.recyclerview.widget.DefaultItemAnimator import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.github.shadowsocks.Core.app import com.github.shadowsocks.Core.app
...@@ -86,11 +89,14 @@ class AppManager : AppCompatActivity() { ...@@ -86,11 +89,14 @@ class AppManager : AppCompatActivity() {
val packageName: String) { val packageName: String) {
val name: CharSequence = appInfo.loadLabel(pm) // cached for sorting val name: CharSequence = appInfo.loadLabel(pm) // cached for sorting
val icon: Drawable get() = appInfo.loadIcon(pm) val icon: Drawable get() = appInfo.loadIcon(pm)
val uid = appInfo.uid
} }
private inner class AppViewHolder(view: View) : RecyclerView.ViewHolder(view), View.OnClickListener { private inner class AppViewHolder(view: View) : RecyclerView.ViewHolder(view), View.OnClickListener {
private val icon = view.findViewById<ImageView>(R.id.itemicon) private val icon = view.findViewById<ImageView>(R.id.itemicon)
private val check = view.findViewById<Switch>(R.id.itemcheck) private val check = view.findViewById<Switch>(R.id.itemcheck)
private val tvTitle = view.findViewById<TextView>(R.id.title)
private val tvDesc = view.findViewById<TextView>(R.id.desc)
private lateinit var item: ProxiedApp private lateinit var item: ProxiedApp
private val proxied get() = proxiedApps.contains(item.packageName) private val proxied get() = proxiedApps.contains(item.packageName)
...@@ -98,10 +104,12 @@ class AppManager : AppCompatActivity() { ...@@ -98,10 +104,12 @@ class AppManager : AppCompatActivity() {
view.setOnClickListener(this) view.setOnClickListener(this)
} }
@SuppressLint("SetTextI18n")
fun bind(app: ProxiedApp) { fun bind(app: ProxiedApp) {
this.item = app this.item = app
icon.setImageDrawable(app.icon) icon.setImageDrawable(app.icon)
check.text = app.name tvTitle.text = app.name
tvDesc.text = "${app.uid}(${app.packageName})"
check.isChecked = proxied check.isChecked = proxied
} }
...@@ -134,7 +142,7 @@ class AppManager : AppCompatActivity() { ...@@ -134,7 +142,7 @@ class AppManager : AppCompatActivity() {
private lateinit var proxiedApps: HashSet<String> private lateinit var proxiedApps: HashSet<String>
private lateinit var toolbar: Toolbar private lateinit var toolbar: Toolbar
private lateinit var bypassSwitch: Switch private lateinit var bypassSwitch: RadioButton
private lateinit var appListView: RecyclerView private lateinit var appListView: RecyclerView
private lateinit var loadingView: View private lateinit var loadingView: View
private val clipboard by lazy { getSystemService<ClipboardManager>()!! } private val clipboard by lazy { getSystemService<ClipboardManager>()!! }
...@@ -181,13 +189,26 @@ class AppManager : AppCompatActivity() { ...@@ -181,13 +189,26 @@ class AppManager : AppCompatActivity() {
DataStore.proxyApps = true DataStore.proxyApps = true
DataStore.dirty = true DataStore.dirty = true
} }
findViewById<Switch>(R.id.onSwitch).setOnCheckedChangeListener { _, checked ->
DataStore.proxyApps = checked val switchListener = { switch: Boolean ->
DataStore.proxyApps = switch
DataStore.dirty = true DataStore.dirty = true
if (!switch) {
finish() finish()
} }
}
val btnOn = findViewById<RadioButton>(R.id.btn_on)
val btnOff = findViewById<RadioButton>(R.id.btn_off)
(if (DataStore.proxyApps) btnOn else btnOff).isChecked = true
btnOn.setOnCheckedChangeListener { _, b ->
if (b) switchListener(true)
}
btnOff.setOnCheckedChangeListener { _, b ->
if (b) switchListener(false)
}
bypassSwitch = findViewById(R.id.bypassSwitch) bypassSwitch = findViewById(R.id.btn_bypass)
bypassSwitch.isChecked = DataStore.bypass bypassSwitch.isChecked = DataStore.bypass
bypassSwitch.setOnCheckedChangeListener { _, checked -> bypassSwitch.setOnCheckedChangeListener { _, checked ->
DataStore.bypass = checked DataStore.bypass = checked
...@@ -198,6 +219,7 @@ class AppManager : AppCompatActivity() { ...@@ -198,6 +219,7 @@ class AppManager : AppCompatActivity() {
loadingView = findViewById(R.id.loading) loadingView = findViewById(R.id.loading)
appListView = findViewById(R.id.list) appListView = findViewById(R.id.list)
appListView.layoutManager = LinearLayoutManager(this, RecyclerView.VERTICAL, false) appListView.layoutManager = LinearLayoutManager(this, RecyclerView.VERTICAL, false)
appListView.addItemDecoration(DividerItemDecoration(this, RecyclerView.VERTICAL))
appListView.itemAnimator = DefaultItemAnimator() appListView.itemAnimator = DefaultItemAnimator()
appListView.adapter = AppsAdapter() appListView.adapter = AppsAdapter()
......
...@@ -8,40 +8,61 @@ ...@@ -8,40 +8,61 @@
android:orientation="vertical" android:orientation="vertical"
android:duplicateParentState="false"> android:duplicateParentState="false">
<include layout="@layout/toolbar_light_dark"/> <include layout="@layout/toolbar_light_dark"/>
<LinearLayout android:layout_width="fill_parent"
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/linearLayout2"
android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:elevation="1dp"
android:background="?android:colorBackground" android:background="?android:colorBackground"
android:orientation="vertical" android:elevation="1dp">
tools:ignore="RtlSymmetry">
<Switch <TextView
android:id="@+id/onSwitch" android:id="@+id/tv_mode"
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:checked="true" android:layout_marginStart="16dp"
android:paddingBottom="12dp" android:text="@string/mode"
android:paddingEnd="16dp" app:layout_constraintBottom_toBottomOf="@+id/radioGroup"
android:paddingStart="72dp" app:layout_constraintStart_toStartOf="parent"
android:paddingTop="12dp" app:layout_constraintTop_toTopOf="@+id/radioGroup" />
android:text="@string/on"
android:textColor="?android:attr/textColorSecondary"
android:textSize="18sp"/>
<Switch <RadioGroup
android:id="@+id/bypassSwitch" android:id="@+id/radioGroup"
android:layout_width="match_parent" android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/tv_mode"
app:layout_constraintTop_toTopOf="parent">
<RadioButton
android:id="@+id/btn_off"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/off" />
<RadioButton
android:id="@+id/btn_on"
android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:checked="true" android:layout_weight="1"
android:paddingBottom="12dp" android:text="@string/on" />
android:paddingEnd="16dp"
android:paddingStart="72dp" <RadioButton
android:paddingTop="12dp" android:id="@+id/btn_bypass"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/bypass_apps" android:text="@string/bypass_apps"
android:textColor="?android:attr/textColorSecondary" android:tooltipText="@string/bypass_apps_summary" />
android:textSize="18sp" </RadioGroup>
android:tooltipText="@string/bypass_apps_summary"/>
</LinearLayout> </androidx.constraintlayout.widget.ConstraintLayout>
<androidx.coordinatorlayout.widget.CoordinatorLayout <androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/snackbar" android:id="@+id/snackbar"
android:layout_width="match_parent" android:layout_width="match_parent"
......
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/linearLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:focusable="true" android:background="?android:attr/selectableItemBackground"
android:background="?android:attr/selectableItemBackground"> android:focusable="true">
<ImageView <ImageView
android:id="@+id/itemicon" android:id="@+id/itemicon"
android:layout_width="72dp" android:layout_width="40dp"
android:layout_height="56dp" android:layout_height="40dp"
android:paddingBottom="4dp" android:layout_marginStart="16dp"
android:paddingEnd="16dp" android:layout_marginTop="8dp"
android:paddingStart="8dp" android:layout_marginBottom="8dp"
android:paddingTop="4dp" android:scaleType="fitCenter"
android:scaleType="fitCenter"/> app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:src="@android:drawable/sym_def_app_icon" />
<TextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="8dp"
android:ellipsize="end"
android:textColor="?android:attr/textColorSecondary"
android:textSize="18sp"
app:layout_constraintEnd_toStartOf="@+id/itemcheck"
app:layout_constraintStart_toEndOf="@+id/itemicon"
app:layout_constraintTop_toTopOf="parent"
tools:text="Package label" />
<TextView
android:id="@+id/desc"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:layout_marginBottom="4dp"
android:ellipsize="end"
android:textColor="?android:attr/textColorTertiary"
android:textSize="12sp"
android:breakStrategy="high_quality"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/title"
app:layout_constraintStart_toStartOf="@+id/title"
app:layout_constraintTop_toBottomOf="@+id/title"
tools:text="10036(com.package.name)" />
<Switch <Switch
android:id="@+id/itemcheck" android:id="@+id/itemcheck"
android:layout_width="0dp" android:layout_width="wrap_content"
android:layout_height="fill_parent" android:layout_height="wrap_content"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:layout_weight="1"
android:clickable="false" android:clickable="false"
android:ellipsize="end"
android:focusable="false" android:focusable="false"
android:focusableInTouchMode="false" android:focusableInTouchMode="false"
android:gravity="center_vertical" app:layout_constraintBottom_toBottomOf="parent"
android:textColor="?android:attr/textColorSecondary" app:layout_constraintEnd_toEndOf="parent"
android:textSize="18sp"/> app:layout_constraintTop_toTopOf="parent" />
</LinearLayout> </androidx.constraintlayout.widget.ConstraintLayout>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment