You've already forked KernelSU-Next
mirror of
https://github.com/KernelSU-Next/KernelSU-Next.git
synced 2025-08-27 23:46:34 +00:00
POC: load icon app via ksu://icon/[packageName] (#674)
* manager: load app icons from package name using AppIconUti Trying basic icon rendering from package via WebView ksu:// scheme. Includes cache and bitmap scaling. Still subject to refinement. * Update WebUIActivity.kt This proof-of-concept intercepts custom URLs of the form: ksu://icon/com.example.app It fetches the app icon using PackageManager via AppIconUtil, converts it to PNG, and returns it as a WebResourceResponse. Used inside shouldInterceptRequest() for early experimentation with dynamic WebView asset routing. Fallbacks to WebViewAssetLoader for all other requests. Notes: - Icon size currently fixed at 512px - No error icon or fallback image yet - No caching headers or mime sniffing implemented * POC: Handle ksu://icon/[packageName] to serve app icon via WebView This proof-of-concept intercepts custom URLs of the form: ksu://icon/com.example.app It fetches the app icon using PackageManager via AppIconUtil, converts it to PNG, and returns it as a WebResourceResponse. Used inside shouldInterceptRequest() for early experimentation with dynamic WebView asset routing. Fallbacks to WebViewAssetLoader for all other requests. Notes: - Icon size currently fixed at 512px - No error icon or fallback image yet - No caching headers or mime sniffing implemented
This commit is contained in:
@@ -0,0 +1,46 @@
|
|||||||
|
package com.rifsxd.ksunext.ui.webui;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.pm.ApplicationInfo;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.drawable.BitmapDrawable;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class AppIconUtil {
|
||||||
|
private static final Map<String, Bitmap> iconCache = new HashMap<>();
|
||||||
|
|
||||||
|
public static Bitmap loadAppIconSync(Context context, String packageName, int sizePx) {
|
||||||
|
Bitmap cached = iconCache.get(packageName);
|
||||||
|
if (cached != null) return cached;
|
||||||
|
|
||||||
|
try {
|
||||||
|
PackageManager pm = context.getPackageManager();
|
||||||
|
ApplicationInfo appInfo = pm.getApplicationInfo(packageName, 0);
|
||||||
|
Drawable drawable = pm.getApplicationIcon(appInfo);
|
||||||
|
Bitmap raw = drawableToBitmap(drawable, sizePx);
|
||||||
|
Bitmap icon = Bitmap.createScaledBitmap(raw, sizePx, sizePx, true);
|
||||||
|
iconCache.put(packageName, icon);
|
||||||
|
return icon;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Bitmap drawableToBitmap(Drawable drawable, int size) {
|
||||||
|
if (drawable instanceof BitmapDrawable) return ((BitmapDrawable) drawable).getBitmap();
|
||||||
|
|
||||||
|
int width = drawable.getIntrinsicWidth() > 0 ? drawable.getIntrinsicWidth() : size;
|
||||||
|
int height = drawable.getIntrinsicHeight() > 0 ? drawable.getIntrinsicHeight() : size;
|
||||||
|
|
||||||
|
Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
||||||
|
Canvas canvas = new Canvas(bmp);
|
||||||
|
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
|
||||||
|
drawable.draw(canvas);
|
||||||
|
return bmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -96,7 +96,23 @@ class WebUIActivity : ComponentActivity() {
|
|||||||
view: WebView,
|
view: WebView,
|
||||||
request: WebResourceRequest
|
request: WebResourceRequest
|
||||||
): WebResourceResponse? {
|
): WebResourceResponse? {
|
||||||
return webViewAssetLoader.shouldInterceptRequest(request.url)
|
val url = request.url
|
||||||
|
|
||||||
|
//POC: Handle ksu://icon/[packageName] to serve app icon via WebView
|
||||||
|
if (url.scheme.equals("ksu", ignoreCase = true) && url.host.equals("icon", ignoreCase = true)) {
|
||||||
|
val packageName = url.path?.substring(1)
|
||||||
|
if (!packageName.isNullOrEmpty()) {
|
||||||
|
val icon = AppIconUtil.loadAppIconSync(this@WebUIActivity, packageName, 512)
|
||||||
|
if (icon != null) {
|
||||||
|
val stream = java.io.ByteArrayOutputStream()
|
||||||
|
icon.compress(android.graphics.Bitmap.CompressFormat.PNG, 100, stream)
|
||||||
|
val inputStream = java.io.ByteArrayInputStream(stream.toByteArray())
|
||||||
|
return WebResourceResponse("image/png", null, inputStream)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return webViewAssetLoader.shouldInterceptRequest(url)
|
||||||
}
|
}
|
||||||
override fun onPageFinished(view: WebView?, url: String?) {
|
override fun onPageFinished(view: WebView?, url: String?) {
|
||||||
super.onPageFinished(view, url)
|
super.onPageFinished(view, url)
|
||||||
@@ -119,4 +135,4 @@ class WebUIActivity : ComponentActivity() {
|
|||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
runCatching { rootShell?.close() }
|
runCatching { rootShell?.close() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user