From 410eff11a9033d6b93e73bd6e866162066c19d74 Mon Sep 17 00:00:00 2001 From: BlueMatthew Date: Tue, 26 Dec 2023 17:19:33 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=BB=91=E5=AE=9A=E7=BD=91?= =?UTF-8?q?=E7=BB=9C=E7=9A=84=E6=8E=A5=E5=8F=A3=E3=80=81=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?usb=E6=91=84=E5=83=8F=E5=A4=B4=E6=8B=8D=E7=85=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 2 +- app/release/output-metadata.json | 20 -- app/src/main/AndroidManifest.xml | 4 +- app/src/main/cpp/MicroPhoto.cpp | 10 +- app/src/main/cpp/PhoneDevice.cpp | 47 ++- app/src/main/cpp/PhoneDevice.h | 6 +- app/src/main/cpp/camera2/ndkcamera.cpp | 20 +- app/src/main/cpp/camera2/ndkcamera.h | 2 +- .../com/xypower/mpapp/ChannelActivity.java | 2 + .../java/com/xypower/mpapp/MainActivity.java | 10 + .../com/xypower/mpapp/MicroPhotoService.java | 123 +++++-- .../main/res/layout-land/activity_main.xml | 11 + app/src/main/res/layout/activity_channel.xml | 10 + app/src/main/res/layout/activity_main.xml | 20 +- app/src/main/res/values/networks.xml | 9 + app/src/main/res/values/strings.xml | 1 + common/build.gradle | 4 +- .../com/xypower/common/MicroPhotoContext.java | 24 +- .../com/xypower/common/TelephonyInfo.java | 305 ++++++++++++++++++ mpmaster/build.gradle | 2 +- mpmaster/src/main/AndroidManifest.xml | 1 + .../com/xypower/mpapp/FloatingWindow.java | 224 +++++++++++++ .../java/com/xypower/mpmaster/AppMaster.java | 1 - 23 files changed, 763 insertions(+), 95 deletions(-) delete mode 100644 app/release/output-metadata.json create mode 100644 app/src/main/res/values/networks.xml create mode 100644 common/src/main/java/com/xypower/common/TelephonyInfo.java create mode 100644 mpmaster/src/main/java/com/xypower/mpapp/FloatingWindow.java diff --git a/app/build.gradle b/app/build.gradle index 955e300a..0f7be024 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -17,7 +17,7 @@ android { applicationId "com.xypower.mpapp" minSdk 25 //noinspection ExpiredTargetSdkVersion - targetSdk 25 + targetSdk 28 versionCode AppVersionCode versionName AppVersionName diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json deleted file mode 100644 index 2366273b..00000000 --- a/app/release/output-metadata.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "version": 3, - "artifactType": { - "type": "APK", - "kind": "Directory" - }, - "applicationId": "com.xinyingpower.microphoto", - "variantName": "release", - "elements": [ - { - "type": "SINGLE", - "filters": [], - "attributes": [], - "versionCode": 101010, - "versionName": "1.0.10", - "outputFile": "app-release.apk" - } - ], - "elementType": "File" -} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 6e39e421..20dfbad6 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -5,6 +5,7 @@ + @@ -80,6 +81,7 @@ - + #include +#include + #ifdef USING_BREAK_PAD #include "client/linux/handler/exception_handler.h" #include "client/linux/handler/minidump_descriptor.h" @@ -168,7 +170,7 @@ Java_com_xypower_mpapp_MainActivity_takePhoto( extern "C" JNIEXPORT jlong JNICALL Java_com_xypower_mpapp_MicroPhotoService_init( JNIEnv* env, - jobject pThis, jstring appPath, jstring ip, jint port, jstring cmdid, jint protocol, jint networkProtocol) { + jobject pThis, jstring appPath, jstring ip, jint port, jstring cmdid, jint protocol, jint networkProtocol, jlong netHandle) { /* google_breakpad::MinidumpDescriptor descriptor("."); @@ -177,6 +179,10 @@ Java_com_xypower_mpapp_MicroPhotoService_init( */ + net_handle_t nh = (net_handle_t)netHandle; + + android_setprocnetwork(nh); + char model[PROP_VALUE_MAX] = { 0 }; __system_property_get("ro.product.model", model); @@ -200,7 +206,7 @@ Java_com_xypower_mpapp_MicroPhotoService_init( CTerminal* pTerminal = NewTerminal(protocol); - CPhoneDevice* device = new CPhoneDevice(vm, pThis, appPathStr); + CPhoneDevice* device = new CPhoneDevice(vm, pThis, appPathStr, NETID_UNSET); device->SetListener(pTerminal); pTerminal->InitServerInfo(appPathStr, cmdidStr, ipStr, port, udpOrTcp); diff --git a/app/src/main/cpp/PhoneDevice.cpp b/app/src/main/cpp/PhoneDevice.cpp index a933095e..02d91dc5 100644 --- a/app/src/main/cpp/PhoneDevice.cpp +++ b/app/src/main/cpp/PhoneDevice.cpp @@ -161,7 +161,7 @@ void CPhoneDevice::CPhoneCamera::on_error(const std::string& msg) } } -CPhoneDevice::CPhoneDevice(JavaVM* vm, jobject service, const std::string& appPath) +CPhoneDevice::CPhoneDevice(JavaVM* vm, jobject service, const std::string& appPath, unsigned int netId) { mCamera = NULL; m_listener = NULL; @@ -171,6 +171,8 @@ CPhoneDevice::CPhoneDevice(JavaVM* vm, jobject service, const std::string& appPa m_javaService = NULL; m_appPath = appPath; + mNetId = netId; + m_vm = vm; JNIEnv* env = NULL; bool didAttachThread = false; @@ -197,6 +199,14 @@ CPhoneDevice::CPhoneDevice(JavaVM* vm, jobject service, const std::string& appPa env->DeleteLocalRef(classService); + jclass classSysApi = env->FindClass("com/dev/devapi/api/SysApi"); + if(classSysApi != NULL) + { + mTurnOtg = env->GetStaticMethodID(classSysApi, "setOtgState","(Z)V"); + env->DeleteLocalRef(classSysApi); + } + + if (didAttachThread) { vm->DetachCurrentThread(); @@ -204,8 +214,6 @@ CPhoneDevice::CPhoneDevice(JavaVM* vm, jobject service, const std::string& appPa m_timerUidFeed = time(NULL) * 1000; m_wakelockIdFeed = (unsigned long)m_timerUidFeed; - - } CPhoneDevice::~CPhoneDevice() @@ -257,6 +265,11 @@ void CPhoneDevice::SetRecognizationCfg(const IDevice::CFG_RECOGNIZATION* pRecogn m_pRecognizationCfg = pRecognizationCfg; } +bool CPhoneDevice::BindNetwork(int sock) +{ + return true; +} + bool CPhoneDevice::UpdateTime(time_t ts) { JNIEnv* env = NULL; @@ -618,9 +631,9 @@ IDevice::timer_uid_t CPhoneDevice::RegisterHeartbeat(unsigned int timerType, uns ALOGE("Failed to get JNI Env"); return 0; } + env->CallVoidMethod(m_javaService, mRegisterHeartbeatMid, (jint)timeout); if (didAttachThread) { - env->CallVoidMethod(m_javaService, mRegisterHeartbeatMid, (jint)timeout); m_vm->DetachCurrentThread(); } @@ -649,6 +662,32 @@ bool CPhoneDevice::TakePhoto(const IDevice::PHOTO_INFO& photoInfo, const vector< params.sensibility = mPhotoInfo.sensibility; params.orientation = mPhotoInfo.orientation; + if (photoInfo.usbCamera) + { + jboolean otgOn = JNI_TRUE; + JNIEnv* env = NULL; + bool didAttachThread = false; + bool res = GetJniEnv(m_vm, &env, didAttachThread); + if (!res) + { + ALOGE("Failed to get JNI Env"); + return false; + } + + jclass classSysApi = env->FindClass("com/dev/devapi/api/SysApi"); + if(classSysApi != NULL) + { + XYLOG(XYLOG_SEVERITY_INFO, "Turn on OTG for USB Camera"); + env->CallStaticVoidMethod(classSysApi, mTurnOtg, otgOn); + env->DeleteLocalRef(classSysApi); + } + + if (didAttachThread) + { + m_vm->DetachCurrentThread(); + } + } + mCamera = new CPhoneCamera(this, photoInfo.width, photoInfo.height, params); if (mCamera->open(to_string(mPhotoInfo.cameraId).c_str()) == 0) { diff --git a/app/src/main/cpp/PhoneDevice.h b/app/src/main/cpp/PhoneDevice.h index 083874fc..2692aaec 100644 --- a/app/src/main/cpp/PhoneDevice.h +++ b/app/src/main/cpp/PhoneDevice.h @@ -162,11 +162,12 @@ public: CPhoneDevice* m_dev; }; - CPhoneDevice(JavaVM* vm, jobject service, const std::string& appPath); + CPhoneDevice(JavaVM* vm, jobject service, const std::string& appPath, unsigned int netId); virtual ~CPhoneDevice(); virtual void SetListener(IListener* listener); virtual void SetRecognizationCfg(const CFG_RECOGNIZATION* pRecognizationCfg); + virtual bool BindNetwork(int sock); virtual bool UpdateTime(time_t ts); virtual bool UpdateSchedules(); virtual bool QuerySystemProperties(map& properties); @@ -241,11 +242,14 @@ protected: jmethodID mEnableGpsMid; jmethodID mRequestPositionMid; + jmethodID mTurnOtg; + std::string mPath; IDevice::PHOTO_INFO mPhotoInfo; vector mOsds; IListener* m_listener; const CFG_RECOGNIZATION* m_pRecognizationCfg; + unsigned int mNetId; atomic_ulong m_timerUidFeed; atomic_ulong m_wakelockIdFeed; diff --git a/app/src/main/cpp/camera2/ndkcamera.cpp b/app/src/main/cpp/camera2/ndkcamera.cpp index a8f33b6f..9a69290b 100644 --- a/app/src/main/cpp/camera2/ndkcamera.cpp +++ b/app/src/main/cpp/camera2/ndkcamera.cpp @@ -117,8 +117,8 @@ NdkCamera::~NdkCamera() } } -int NdkCamera::open(const char* cameraId) { - ALOGW("DBG::open %s", cameraId); +int NdkCamera::open(const std::string& cameraId) { + ALOGW("DBG::open %s", cameraId.c_str()); // camera_facing = _camera_facing; @@ -136,7 +136,7 @@ int NdkCamera::open(const char* cameraId) { for (int i = 0; i < camera_id_list->numCameras; ++i) { const char *id = camera_id_list->cameraIds[i]; - if (strcmp(id, cameraId) != 0) { + if (cameraId.compare(id) != 0) { continue; } ACameraMetadata * camera_metadata = 0; @@ -164,7 +164,8 @@ int NdkCamera::open(const char* cameraId) { // continue; } - camera_id = id; + camera_id = cameraId; + camera_id.assign(id, strlen(id)); // query orientation int orientation = 0; @@ -177,10 +178,9 @@ int NdkCamera::open(const char* cameraId) { camera_orientation = orientation; - { ACameraMetadata_const_entry e = {0}; - ACameraMetadata_getConstEntry(camera_metadata, + camera_status_t status = ACameraMetadata_getConstEntry(camera_metadata, ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, &e); // format of the data: format, width, height, input?, type int32 @@ -299,7 +299,7 @@ int NdkCamera::open(const char* cameraId) { } if (camera_id == "2") { - camera_orientation += 180; + // camera_orientation += 180; } mCameraId = camera_id; @@ -658,13 +658,11 @@ void NdkCamera::onCaptureCompleted(ACameraCaptureSession* session, ACaptureReque ACameraMetadata_const_entry val = { 0 }; camera_status_t status = ACameraMetadata_getConstEntry(result, ACAMERA_SENSOR_EXPOSURE_TIME, &val); - int64_t exTime = val.data.i64[0]; - - + int64_t exTime = (status == ACAMERA_OK) ? val.data.i64[0] : -1; val = { 0 }; status = ACameraMetadata_getConstEntry(result, ACAMERA_CONTROL_AE_MODE, &val); - uint8_t aeMode = val.data.u8[0]; + uint8_t aeMode = (status == ACAMERA_OK) ? val.data.u8[0] : 0; // ACaptureRequest_setEntry_i32(capture_request, ACAMERA_SENSOR_SENSITIVITY, 1, &sensitivity_); ALOGD("onCaptureCompleted EXPOSURE_TIME=%lld, camera id=%s, AE=%s", exTime, mCameraId.c_str(), ((aeMode == 1) ? "ON" : "OFF")); diff --git a/app/src/main/cpp/camera2/ndkcamera.h b/app/src/main/cpp/camera2/ndkcamera.h index b861b537..5d15e8d1 100644 --- a/app/src/main/cpp/camera2/ndkcamera.h +++ b/app/src/main/cpp/camera2/ndkcamera.h @@ -52,7 +52,7 @@ public: virtual ~NdkCamera(); // facing 0=front 1=back - int open(const char* cameraId); + int open(const std::string& cameraId); void close(); void onImageAvailable(AImageReader* reader); diff --git a/app/src/main/java/com/xypower/mpapp/ChannelActivity.java b/app/src/main/java/com/xypower/mpapp/ChannelActivity.java index 8d1c9596..bdd79aed 100644 --- a/app/src/main/java/com/xypower/mpapp/ChannelActivity.java +++ b/app/src/main/java/com/xypower/mpapp/ChannelActivity.java @@ -135,6 +135,7 @@ public class ChannelActivity extends AppCompatActivity { } JSONObject jsonObject = stringBuilder != null ? (new JSONObject(stringBuilder.toString())) : new JSONObject(); + binding.btnUsbCamera.setChecked(jsonObject.optInt("usbCamera", 0) == 1); binding.btnAutoExplosure.setChecked(jsonObject.optInt("autoExposure", 1) == 1); binding.btnAutoFocus.setChecked(jsonObject.optInt("autoFocus", 1) == 1); binding.btnHdrMode.setChecked(jsonObject.optInt("hdr", 1) == 1); @@ -248,6 +249,7 @@ public class ChannelActivity extends AppCompatActivity { } try { + jsonObject.put("usbCamera", binding.btnUsbCamera.isChecked() ? 1 : 0); jsonObject.put("autoExposure", binding.btnAutoExplosure.isChecked() ? 1 : 0); jsonObject.put("autoFocus", binding.btnAutoFocus.isChecked() ? 1 : 0); jsonObject.put("hdrMode", binding.btnHdrMode.isChecked() ? 1 : 0); diff --git a/app/src/main/java/com/xypower/mpapp/MainActivity.java b/app/src/main/java/com/xypower/mpapp/MainActivity.java index 253508b3..fdfdc1db 100644 --- a/app/src/main/java/com/xypower/mpapp/MainActivity.java +++ b/app/src/main/java/com/xypower/mpapp/MainActivity.java @@ -112,6 +112,7 @@ public class MainActivity extends AppCompatActivity { binding = ActivityMainBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); // getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); ActionBar actionBar = getSupportActionBar(); @@ -223,6 +224,10 @@ public class MainActivity extends AppCompatActivity { binding.heartbeat.setText((appConfig.heartbeat > 0) ? Integer.toString(appConfig.heartbeat) : ""); binding.packetSize.setText((appConfig.packetSize > 0) ? Integer.toString(appConfig.packetSize) : ""); + if (appConfig.network < binding.network.getCount()) { + binding.network.setSelection(appConfig.network); + } + this.binding.startServBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { @@ -487,6 +492,7 @@ public class MainActivity extends AppCompatActivity { intent.putExtra("port", curAppConfig.port); intent.putExtra("protocol", curAppConfig.protocol); intent.putExtra("networkProtocol", curAppConfig.networkProtocol); + intent.putExtra("network", curAppConfig.network); if (messenger != null) { intent.putExtra("messenger", messenger); } @@ -508,6 +514,7 @@ public class MainActivity extends AppCompatActivity { mLogFileObserver = new LogFileObserver(logFilePath); mLogFileObserver.startWatching(); + Log.i(TAG, "Log Observer Started"); } @Override @@ -518,6 +525,7 @@ public class MainActivity extends AppCompatActivity { if (mLogFileObserver != null) { mLogFileObserver.stopWatching(); mLogFileObserver = null; + Log.i(TAG, "Log Observer Stopped"); } } @@ -559,6 +567,8 @@ public class MainActivity extends AppCompatActivity { appConfig.heartbeat = TextUtils.isEmpty(binding.heartbeat.getText().toString()) ? 0 : Integer.parseInt(binding.heartbeat.getText().toString()); appConfig.packetSize = TextUtils.isEmpty(binding.packetSize.getText().toString()) ? 0 : Integer.parseInt(binding.packetSize.getText().toString()); + appConfig.network = MainActivity.this.binding.network.getSelectedItemPosition(); + saveAppConfig(appConfig); return appConfig; diff --git a/app/src/main/java/com/xypower/mpapp/MicroPhotoService.java b/app/src/main/java/com/xypower/mpapp/MicroPhotoService.java index b34852ee..dbbc41ac 100644 --- a/app/src/main/java/com/xypower/mpapp/MicroPhotoService.java +++ b/app/src/main/java/com/xypower/mpapp/MicroPhotoService.java @@ -1,5 +1,6 @@ package com.xypower.mpapp; +import static java.lang.System.in; import static java.lang.System.loadLibrary; import android.app.AlarmManager; @@ -18,6 +19,10 @@ import android.location.LocationListener; import android.location.LocationManager; import android.location.LocationProvider; import android.net.ConnectivityManager; +import android.net.Network; +import android.net.NetworkCapabilities; +import android.net.NetworkInfo; +import android.net.NetworkRequest; import android.net.Uri; import android.net.wifi.WifiManager; import android.os.BatteryManager; @@ -553,43 +558,51 @@ public class MicroPhotoService extends Service { mMessenger = intent.getParcelableExtra("messenger"); } - String appPath = MicroPhotoContext.buildAppDir(this.getApplicationContext()); - - String server = intent.getStringExtra("server"); - int port = intent.getIntExtra("port", 0); - String cmdid = intent.getStringExtra("cmdid"); - int protocol = intent.getIntExtra("protocol", 0); - int networkProtocol = intent.getIntExtra("networkProtocol", 0); - - if (!InetAddressUtils.isIPv4Address(server) && !InetAddressUtils.isIPv6Address(server)) { - // It is a domain - InetAddress addr = null; - try { - addr = InetAddress.getByName(server); - } catch (Exception e) { - e.printStackTrace(); - } - if (addr != null) { - server = addr.getHostAddress(); - } - } - Log.i(TAG, "AppPath=" + appPath + " Server=" + server + ":" + port + " cmdid=" + cmdid + " Protocol=" + protocol + " Network=" + networkProtocol); + int network = intent.getIntExtra("network", 0); + + if (network == 0) { + startTerminalService(intent); + } else { + ConnectivityManager cm =(ConnectivityManager) getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE); + + NetworkRequest.Builder builder = new NetworkRequest.Builder(); + builder.addCapability(NetworkCapabilities.NET_CAPABILITY_DUN); + builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); + + List availableNetworkInfos = new ArrayList<>(); + + cm.registerNetworkCallback(builder.build(), new ConnectivityManager.NetworkCallback() { - MicroPhotoService service = MicroPhotoService.this; + @Override + public void onAvailable(Network network) { + super.onAvailable(network); - service.mNativeHandle = init(appPath, server, port, cmdid, protocol, networkProtocol); + availableNetworkInfos.add(cm.getNetworkInfo(network)); - if (service.mNativeHandle !=0) { - service.mCmdid = cmdid; - Date date = new Date(); - long nowTs = date.getTime() / 1000; - date.setHours(0); - date.setMinutes(0); - date.setSeconds(0); - long startTime = date.getTime() / 1000; - long baseTime = nowTs - startTime; + Log.i(TAG, "Network"); + } - service.registerCaptureSchedule(startTime, baseTime); + }); + + NetworkInfo[] networkInfos = cm.getAllNetworkInfo(); + + for (NetworkInfo ni : networkInfos) { + if (ni.getType() == ConnectivityManager.TYPE_MOBILE || + ni.getType() == ConnectivityManager.TYPE_MOBILE_DUN || + ni.getType() == ConnectivityManager.TYPE_WIFI) { + + // availableNetworkInfos.add(ni); + } + } + Network[] networks = cm.getAllNetworks(); + + for (Network nw : networks) { + NetworkInfo nwi = cm.getNetworkInfo(nw); + String name = nwi.toString(); + if (name.equals("")) { + + } + } } break; @@ -607,6 +620,48 @@ public class MicroPhotoService extends Service { return START_NOT_STICKY; } + private void startTerminalService(Intent intent) { + + String appPath = MicroPhotoContext.buildAppDir(this.getApplicationContext()); + + String server = intent.getStringExtra("server"); + int port = intent.getIntExtra("port", 0); + String cmdid = intent.getStringExtra("cmdid"); + int protocol = intent.getIntExtra("protocol", 0); + int networkProtocol = intent.getIntExtra("networkProtocol", 0); + + if (!InetAddressUtils.isIPv4Address(server) && !InetAddressUtils.isIPv6Address(server)) { + // It is a domain + InetAddress addr = null; + try { + addr = InetAddress.getByName(server); + } catch (Exception e) { + e.printStackTrace(); + } + if (addr != null) { + server = addr.getHostAddress(); + } + } + Log.i(TAG, "AppPath=" + appPath + " Server=" + server + ":" + port + " cmdid=" + cmdid + " Protocol=" + protocol + " Network=" + networkProtocol); + + MicroPhotoService service = MicroPhotoService.this; + + service.mNativeHandle = init(appPath, server, port, cmdid, protocol, networkProtocol, 0); + + if (service.mNativeHandle !=0) { + service.mCmdid = cmdid; + Date date = new Date(); + long nowTs = date.getTime() / 1000; + date.setHours(0); + date.setMinutes(0); + date.setSeconds(0); + long startTime = date.getTime() / 1000; + long baseTime = nowTs - startTime; + + service.registerCaptureSchedule(startTime, baseTime); + } + } + public void requestWakelock(String name, long timeout) { PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE); PowerManager.WakeLock wl = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK/* | PowerManager.ON_AFTER_RELEASE*/, name); @@ -923,7 +978,7 @@ CellSignalStrengthGsm cellSignalStrengthGsm = cellInfoGsm.getCellSignalStrength( cellSignalStrengthGsm.getDbm(); */ - protected native long init(String appPath, String ip, int port, String cmdid, int protocol, int networkProtocl); + protected native long init(String appPath, String ip, int port, String cmdid, int protocol, int networkProtocl, long netHandle); protected native long getHeartbeatDuration(long handler); protected native long[] getPhotoTimeData(long handler); // protected native long[] getNextScheduleItem(long handler); diff --git a/app/src/main/res/layout-land/activity_main.xml b/app/src/main/res/layout-land/activity_main.xml index 97480e92..4f9b95f9 100644 --- a/app/src/main/res/layout-land/activity_main.xml +++ b/app/src/main/res/layout-land/activity_main.xml @@ -140,6 +140,17 @@ app:layout_constraintLeft_toRightOf="@+id/textViewPacketSize" app:layout_constraintTop_toBottomOf="@+id/server" /> + +