From 74358c21c1c0412787174a2a5691d0d27c0a5192 Mon Sep 17 00:00:00 2001 From: Matthew Date: Fri, 16 Aug 2024 15:46:54 +0800 Subject: [PATCH] =?UTF-8?q?=E9=80=9A=E8=BF=87ContentProvider=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E6=9F=A5=E8=AF=A2=E5=92=8C=E5=8A=A8=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 34 +- .../com/xypower/mpapp/BridgeProvider.java | 344 ++++++++++++++++++ 2 files changed, 363 insertions(+), 15 deletions(-) create mode 100644 app/src/main/java/com/xypower/mpapp/BridgeProvider.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index dc25f814..f32efefc 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -83,19 +83,23 @@ android:supportsRtl="true" android:theme="@style/Theme.MicroPhoto" tools:targetApi="28"> + + + android:exported="true" /> - + android:process=":bridge_proc" + android:screenOrientation="landscape" /> - - - + + + + \ No newline at end of file diff --git a/app/src/main/java/com/xypower/mpapp/BridgeProvider.java b/app/src/main/java/com/xypower/mpapp/BridgeProvider.java new file mode 100644 index 00000000..27a0e532 --- /dev/null +++ b/app/src/main/java/com/xypower/mpapp/BridgeProvider.java @@ -0,0 +1,344 @@ +package com.xypower.mpapp; + +import android.content.ContentProvider; +import android.content.ContentValues; +import android.content.Context; +import android.content.Intent; +import android.content.UriMatcher; +import android.database.Cursor; +import android.database.MatrixCursor; +import android.net.Uri; +import android.text.TextUtils; +import android.util.Base64; +import android.util.Log; + +import com.xypower.common.FilesUtils; +import com.xypower.common.JSONUtils; +import com.xypower.common.MicroPhotoContext; + +import org.json.JSONObject; + +import java.io.File; + +public class BridgeProvider extends ContentProvider { + + private final static String TAG = "MPLOG"; + private final static String AUTHORITY = "com.xypower.mpapp.provider"; + private final static String PATH_QUERY_SEC_VERSION = "/querySecVersion"; + private final static String PATH_QUERY_BATTERY_VOLTAGE = "/queryBatVol"; + private final static String PATH_IMP_PRI_KEY = "/importPriKey"; + private final static String PATH_IMP_PUB_KEY = "/importPubKey"; + private final static String PATH_GEN_KEYS = "/genKeys"; + private final static String PATH_GEN_CERT_REQ = "/genCertReq"; + + private final static String PATH_TAKE_PHOTO = "/takePhoto"; + private final static String PATH_TAKE_VIDEO = "/takeVideo"; + + public BridgeProvider() { + Log.i(TAG, "BridgeProvider"); + } + + @Override + public int delete(Uri uri, String selection, String[] selectionArgs) { + // Implement this to handle requests to delete one or more rows. + throw new UnsupportedOperationException("Not yet implemented"); + } + + @Override + public String getType(Uri uri) { + // TODO: Implement this to handle requests for the MIME type of the data + // at the given URI. + throw new UnsupportedOperationException("Not yet implemented"); + } + + @Override + public Uri insert(Uri uri, ContentValues values) { + + + return null; + } + + @Override + public boolean onCreate() { + // TODO: Implement this to initialize your content provider on startup. + return true; + } + + @Override + public Cursor query(Uri uri, String[] projection, String selection, + String[] selectionArgs, String sortOrder) { + UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH); + + Log.i(TAG, uri.toString()); + matcher.addURI(AUTHORITY, PATH_QUERY_SEC_VERSION, 1); + matcher.addURI(AUTHORITY, PATH_QUERY_BATTERY_VOLTAGE, 2); + + + Cursor cursor = null; + int matched = matcher.match(uri); + switch (matched) { + case 1: + cursor = querySecVersion(); + break; + case 2: + cursor = queryBattaryVoltage(); + break; + default: + break; + } + + return cursor; + } + + @Override + public int update(Uri uri, ContentValues values, String selection, + String[] selectionArgs) { + UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH); + + matcher.addURI(AUTHORITY, PATH_IMP_PRI_KEY, 1); + matcher.addURI(AUTHORITY, PATH_IMP_PUB_KEY, 2); + matcher.addURI(AUTHORITY, PATH_GEN_KEYS, 3); + matcher.addURI(AUTHORITY, PATH_GEN_CERT_REQ, 4); + matcher.addURI(AUTHORITY, PATH_TAKE_PHOTO, 5); + matcher.addURI(AUTHORITY, PATH_TAKE_VIDEO, 6); + + int res = 0; + int matched = matcher.match(uri); + switch (matched) { + case 1: + res = importPrivateKey(uri, values); + break; + case 2: + res = importPublicKey(uri, values); + break; + case 3: + res = genKeys(uri, values); + break; + case 4: + res = genCertReq(uri, values); + break; + case 5: + res = takePhoto(uri, values); + break; + case 6: + res = takeVideo(uri, values); + break; + default: + break; + } + + return res; + } + + private Cursor querySecVersion() { + // String resultFile = intent.getStringExtra("resultFile"); + String version = MicroPhotoService.querySecVersion(); + String[] columns = { "version" }; + MatrixCursor matrixCursor = new MatrixCursor(columns, 1); + matrixCursor.addRow(new Object[] { version }); + return matrixCursor; + } + + private Cursor queryBattaryVoltage() { + // #define CMD_GET_CHARGING_BUS_VOLTAGE_STATE 112 + // #define CMD_GET_BAT_VOL_STATE 115 + // #define CMD_GET_BAT_BUS_VOLTAGE_STATE 117 + int bv = MicroPhotoService.getGpioInt(117); + int bcv = MicroPhotoService.getGpioInt(112); + String[] columns = { "bv", "bcv" }; + MatrixCursor matrixCursor = new MatrixCursor(columns, 1); + matrixCursor.addRow(new Object[] { Integer.valueOf(bv), Integer.valueOf(bcv) }); + return matrixCursor; + } + + + private int importPrivateKey(Uri uri, ContentValues values) { + String cert = values.containsKey("cert") ? values.getAsString("cert") : null; + String path = values.containsKey("path") ? values.getAsString("path") : null; + String resultFile = values.containsKey("resultFile") ? values.getAsString("path") : null; + int index = values.containsKey("index") ? values.getAsInteger("index").intValue() : 0; + + boolean res = false; + if (!TextUtils.isEmpty(cert)) { + // Import + byte[] content = Base64.decode(cert, Base64.DEFAULT); + if (content != null) { + res = MicroPhotoService.importPrivateKey(index, content); + } + } else if (TextUtils.isEmpty(path)) { + String md5 = values.containsKey("md5") ? values.getAsString("md5") : null; + File file = new File(path); + if (file.exists() && file.isFile()) { + res = MicroPhotoService.importPrivateKeyFile(index, path, md5); + } + } + + return res ? 1 : 0; + /* + Log.i(TAG, "Import Private Key result=" + (res ? "1" : "0")); + + if (!TextUtils.isEmpty(resultFile)) { + FilesUtils.ensureParentDirectoryExisted(resultFile); + FilesUtils.writeTextFile(resultFile, res ? "1" : "0"); + } + */ + } + + private int importPublicKey(Uri uri, ContentValues values) { + String cert = values.containsKey("cert") ? values.getAsString("cert") : null; + String path = values.containsKey("path") ? values.getAsString("path") : null; + String resultFile = values.containsKey("resultFile") ? values.getAsString("path") : null; + int index = values.containsKey("index") ? values.getAsInteger("index").intValue() : 0; + + boolean res = false; + if (!TextUtils.isEmpty(cert)) { + // Import + byte[] content = Base64.decode(cert, Base64.DEFAULT); + if (content != null) { + res = MicroPhotoService.importPublicKey(index, content); + } + } else if (TextUtils.isEmpty(path)) { + String md5 = values.containsKey("md5") ? values.getAsString("md5") : null; + File file = new File(path); + if (file.exists() && file.isFile()) { + res = MicroPhotoService.importPublicKeyFile(index, path, md5); + } + } + + return res ? 1 : 0; + /* + Log.i(TAG, "Import Private Key result=" + (res ? "1" : "0")); + + if (!TextUtils.isEmpty(resultFile)) { + FilesUtils.ensureParentDirectoryExisted(resultFile); + FilesUtils.writeTextFile(resultFile, res ? "1" : "0"); + } + */ + } + + private int genKeys(Uri uri, ContentValues values) { + int index = values.containsKey("index") ? values.getAsInteger("index").intValue() : 0; + boolean res = MicroPhotoService.genKeys(index); + return res ? 1 : 0; + } + + private int genCertReq(Uri uri, ContentValues values) { + int index = values.containsKey("index") ? values.getAsInteger("index").intValue() : 0; + int type = values.containsKey("type") ? values.getAsInteger("type").intValue() : 0; + String subject = values.containsKey("subject") ? values.getAsString("subject") : null; + String path = values.containsKey("path") ? values.getAsString("path") : null; + + if (TextUtils.isEmpty(subject) || TextUtils.isEmpty(path)) { + return 0; + } + + boolean res = MicroPhotoService.genCertRequest(index, type, subject, path); + return res ? 1 : 0; + } + + private int takePhoto(Uri uri, ContentValues values) { + String path = values.containsKey("path") ? values.getAsString("path") : null; + int channel = values.containsKey("channel") ? values.getAsInteger("channel").intValue() : 1; + int preset = values.containsKey("preset") ? values.getAsInteger("preset").intValue() : 0xFF; + + int width = values.containsKey("width") ? values.getAsInteger("width").intValue() : 0; + int height = values.containsKey("height") ? values.getAsInteger("height").intValue() : 0; + + String leftTopOsd = values.containsKey("leftTopOsd") ? values.getAsString("leftTopOsd") : null; + String rightTopOsd = values.containsKey("rightTopOsd") ? values.getAsString("rightTopOsd") : null; + String rightBottomOsd = values.containsKey("rightBottomOsd") ? values.getAsString("rightBottomOsd") : null; + String leftBottomOsd = values.containsKey("leftBottomOsd") ? values.getAsString("leftBottomOsd") : null; + + String appPath = MicroPhotoContext.buildMpAppDir(getContext()); + File configFile = new File(appPath); + configFile = new File(configFile, "data/channels/" + Integer.toString(channel) + ".json"); + + File tmpConfigFile = new File(appPath); + tmpConfigFile = new File(tmpConfigFile, "tmp/" + Integer.toString(channel) + "-" + Long.toString(System.currentTimeMillis()) + ".json"); + + if (configFile.exists()) { + try { + FilesUtils.copyFile(configFile, tmpConfigFile); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + JSONObject configJson = JSONUtils.loadJson(tmpConfigFile.getAbsolutePath()); + try { + if (configJson == null) { + configJson = new JSONObject(); + } + if (width > 0) { + configJson.put("resolutionCX", width); + } + if (height > 0) { + configJson.put("resolutionCY", height); + } + + JSONObject osdJson = configJson.getJSONObject("osd"); + if (osdJson == null) { + osdJson = configJson.put("osd", new JSONObject()); + } + osdJson.put("leftTop", TextUtils.isEmpty(leftTopOsd) ? "" : leftTopOsd); + osdJson.put("rightTop", TextUtils.isEmpty(rightTopOsd) ? "" : rightTopOsd); + osdJson.put("rightBottom", TextUtils.isEmpty(rightBottomOsd) ? "" : rightBottomOsd); + osdJson.put("leftBottom", TextUtils.isEmpty(leftBottomOsd) ? "" : leftBottomOsd); + + JSONUtils.saveJson(tmpConfigFile.getAbsolutePath(), configJson); + } catch (Exception ex) { + ex.printStackTrace(); + } + + File file = new File(path); + if (file.exists()) { + file.delete(); + } else { + FilesUtils.ensureParentDirectoryExisted(path); + } + + MicroPhotoService.takePhoto(channel, preset, true, tmpConfigFile.getAbsolutePath(), path); + if (tmpConfigFile.exists()) { + tmpConfigFile.delete(); + } + + return 1; + } + + private int takeVideo(Uri uri, ContentValues values) { + String path = values.containsKey("path") ? values.getAsString("path") : null; + int channel = values.containsKey("channel") ? values.getAsInteger("channel").intValue() : 1; + int preset = values.containsKey("preset") ? values.getAsInteger("preset").intValue() : 0xFF; + + int width = values.containsKey("width") ? values.getAsInteger("width").intValue() : 0; + int height = values.containsKey("height") ? values.getAsInteger("height").intValue() : 0; + + int quality = values.containsKey("quality") ? values.getAsInteger("quality").intValue() : 0; + int cameraId = values.containsKey("cameraId") ? values.getAsInteger("cameraId").intValue() : -1; + int duration = values.containsKey("duration") ? values.getAsInteger("duration").intValue() : 15; + + int orientation = values.containsKey("orientation") ? values.getAsInteger("orientation").intValue() : 0; + + long videoId = System.currentTimeMillis() / 1000; + + String leftTopOsd = values.containsKey("leftTopOsd") ? values.getAsString("leftTopOsd") : null; + String rightTopOsd = values.containsKey("rightTopOsd") ? values.getAsString("rightTopOsd") : null; + String rightBottomOsd = values.containsKey("rightBottomOsd") ? values.getAsString("rightBottomOsd") : null; + String leftBottomOsd = values.containsKey("leftBottomOsd") ? values.getAsString("leftBottomOsd") : null; + + if (cameraId == -1) { + cameraId = channel - 1; + } + + Context context = getContext(); + + Intent recordingIntent = MicroPhotoService.makeRecordingIntent(context, + cameraId, videoId, duration, width, height, quality, orientation, + leftTopOsd, rightTopOsd, rightBottomOsd, leftBottomOsd); + + recordingIntent.putExtra("ActivityResult", false); + context.startActivity(recordingIntent); + + return 1; + } +} \ No newline at end of file