From 8808e9b818e78363cab97284198a2875129e47a8 Mon Sep 17 00:00:00 2001 From: Adithya R Date: Wed, 31 May 2023 15:41:06 +0530 Subject: [PATCH] dubai: Disable 5G when front camera is in use On some network(s) (confirmed on Jio), the usage of 5G kills front camera and crashes the camera app. Logs reveal hardware or firmware issues related to interference or bandwidth, which is out of my expertise: [ 63.301897] CAM_ERR: CAM-ISP: cam_ife_csid_irq: 5016 CSID:2 RX_ERROR_LANE0_FIFO_OVERFLOW: Skew/Less Data on lanes/ Slow csid clock:300000000Hz Until this can be actually fixed (if ever), a temporary workaround. Inspired by https://github.com/ArrowOS-Devices/android_device_xiaomi_sweet/commit/a860cc81897a3a0fc259938013721306b02dd386 Change-Id: Ifefb36cf113a5f25feda771ea7729418553e74ed --- camera/Android.bp | 22 +++ camera/AndroidManifest.xml | 34 ++++ ...privapp-permissions-dubaicameraservice.xml | 11 ++ .../dubaicameraservice/BootReceiver.java | 22 +++ .../DubaiCameraService.java | 153 ++++++++++++++++++ device.mk | 1 + 6 files changed, 243 insertions(+) create mode 100644 camera/Android.bp create mode 100644 camera/AndroidManifest.xml create mode 100644 camera/privapp-permissions-dubaicameraservice.xml create mode 100644 camera/src/com/arrow/dubaicameraservice/BootReceiver.java create mode 100644 camera/src/com/arrow/dubaicameraservice/DubaiCameraService.java diff --git a/camera/Android.bp b/camera/Android.bp new file mode 100644 index 0000000..5ea1559 --- /dev/null +++ b/camera/Android.bp @@ -0,0 +1,22 @@ +// +// Copyright (C) 2023 ArrowOS +// +// SPDX-License-Identifier: Apache-2.0 +// + +android_app { + name: "DubaiCameraService", + srcs: ["src/**/*.java"], + certificate: "platform", + platform_apis: true, + privileged: true, + system_ext_specific: true, + required: ["privapp-permissions-dubaicameraservice.xml"], +} + +prebuilt_etc { + name: "privapp-permissions-dubaicameraservice.xml", + src: "privapp-permissions-dubaicameraservice.xml", + system_ext_specific: true, + sub_dir: "permissions", +} diff --git a/camera/AndroidManifest.xml b/camera/AndroidManifest.xml new file mode 100644 index 0000000..26526e5 --- /dev/null +++ b/camera/AndroidManifest.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/camera/privapp-permissions-dubaicameraservice.xml b/camera/privapp-permissions-dubaicameraservice.xml new file mode 100644 index 0000000..0b11906 --- /dev/null +++ b/camera/privapp-permissions-dubaicameraservice.xml @@ -0,0 +1,11 @@ + + + + + + + + diff --git a/camera/src/com/arrow/dubaicameraservice/BootReceiver.java b/camera/src/com/arrow/dubaicameraservice/BootReceiver.java new file mode 100644 index 0000000..206385b --- /dev/null +++ b/camera/src/com/arrow/dubaicameraservice/BootReceiver.java @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2023 ArrowOS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package com.arrow.dubaicameraservice; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; + +public class BootReceiver extends BroadcastReceiver { + + @Override + public void onReceive(final Context context, Intent intent) { + if (!intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) + return; + + DubaiCameraService.startService(context); + } +} diff --git a/camera/src/com/arrow/dubaicameraservice/DubaiCameraService.java b/camera/src/com/arrow/dubaicameraservice/DubaiCameraService.java new file mode 100644 index 0000000..195039a --- /dev/null +++ b/camera/src/com/arrow/dubaicameraservice/DubaiCameraService.java @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2023 ArrowOS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package com.arrow.dubaicameraservice; + +import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; +import static android.telephony.TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_CARRIER; +import static android.telephony.TelephonyManager.NETWORK_TYPE_BITMASK_NR; + +import android.app.Service; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.hardware.camera2.CameraManager; +import android.os.Handler; +import android.os.HandlerExecutor; +import android.os.IBinder; +import android.os.Looper; +import android.os.UserHandle; +import android.telephony.SubscriptionManager; +import android.telephony.TelephonyCallback; +import android.telephony.TelephonyManager; +import android.util.Log; + +import java.util.concurrent.Executor; + +public class DubaiCameraService extends Service { + + private static final boolean DEBUG = false; + private static final String TAG = "DubaiCameraService"; + + private static final String FRONT_CAMERA_ID = "1"; + + private CameraManager mCameraManager; + private SubscriptionManager mSubManager; + private TelephonyManager mTelephonyManager; + + private boolean mIsFrontCamInUse = false; + private int mSubId = INVALID_SUBSCRIPTION_ID; + + private final Handler mHandler = new Handler(Looper.getMainLooper()); + private final Executor mExecutor = new HandlerExecutor(mHandler); + + private final CameraManager.AvailabilityCallback mCameraCallback = + new CameraManager.AvailabilityCallback() { + @Override + public void onCameraAvailable(String cameraId) { + dlog("onCameraAvailable id:" + cameraId); + if (cameraId.equals(FRONT_CAMERA_ID)) { + mIsFrontCamInUse = false; + update5gState(); + } + } + + @Override + public void onCameraUnavailable(String cameraId) { + dlog("onCameraUnavailable id:" + cameraId); + if (cameraId.equals(FRONT_CAMERA_ID)) { + mIsFrontCamInUse = true; + update5gState(); + } + } + }; + + private final SubscriptionManager.OnSubscriptionsChangedListener mSubListener = + new SubscriptionManager.OnSubscriptionsChangedListener() { + @Override + public void onSubscriptionsChanged() { + dlog("onSubscriptionsChanged"); + update5gState(); + } + }; + + private class ActiveDataSubIdCallback extends TelephonyCallback implements + TelephonyCallback.ActiveDataSubscriptionIdListener { + @Override + public void onActiveDataSubscriptionIdChanged(int subId) { + dlog("onActiveDataSubscriptionIdChanged subId:" + subId); + mSubId = subId; + update5gState(); + } + }; + + private final TelephonyCallback mTelephonyCallback = new ActiveDataSubIdCallback(); + + @Override + public void onCreate() { + dlog("onCreate"); + mCameraManager = getSystemService(CameraManager.class); + mSubManager = getSystemService(SubscriptionManager.class); + mTelephonyManager = getSystemService(TelephonyManager.class); + + mCameraManager.registerAvailabilityCallback(mCameraCallback, mHandler); + mTelephonyManager.registerTelephonyCallback(mExecutor, mTelephonyCallback); + mSubManager.addOnSubscriptionsChangedListener(mExecutor, mSubListener); + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + dlog("onStartCommand"); + return START_STICKY; + } + + @Override + public void onDestroy() { + dlog("onDestroy"); + mCameraManager.unregisterAvailabilityCallback(mCameraCallback); + mTelephonyManager.unregisterTelephonyCallback(mTelephonyCallback); + mSubManager.removeOnSubscriptionsChangedListener(mSubListener); + } + + @Override + public IBinder onBind(Intent intent) { + return null; + } + + public static void startService(Context context) { + Log.i(TAG, "Starting service"); + context.startServiceAsUser(new Intent(context, DubaiCameraService.class), + UserHandle.CURRENT); + } + + private void update5gState() { + if (mSubId == INVALID_SUBSCRIPTION_ID + || mSubManager.getActiveSubscriptionIdList().length <= 0) { + dlog("update5gState: Invalid subid or no active subs!"); + return; + } + final TelephonyManager tm = mTelephonyManager.createForSubscriptionId(mSubId); + // Arguably we should use ALLOWED_NETWORK_TYPES_REASON_POWER here but that's already + // used by battery saver, and we are out of other reasons + long allowedNetworkTypes = tm.getAllowedNetworkTypesForReason( + ALLOWED_NETWORK_TYPES_REASON_CARRIER); + final boolean is5gAllowed = (allowedNetworkTypes & NETWORK_TYPE_BITMASK_NR) != 0; + dlog("update5gState mIsFrontCamInUse:" + mIsFrontCamInUse + " is5gAllowed:" + is5gAllowed); + if (mIsFrontCamInUse && is5gAllowed) { + allowedNetworkTypes &= ~NETWORK_TYPE_BITMASK_NR; + } else if (!mIsFrontCamInUse && !is5gAllowed) { + allowedNetworkTypes |= NETWORK_TYPE_BITMASK_NR; + } else { + return; + } + tm.setAllowedNetworkTypesForReason(ALLOWED_NETWORK_TYPES_REASON_CARRIER, + allowedNetworkTypes); + } + + private static void dlog(String msg) { + if (DEBUG) Log.d(TAG, msg); + } +} diff --git a/device.mk b/device.mk index c5adcc9..afa5475 100644 --- a/device.mk +++ b/device.mk @@ -55,6 +55,7 @@ PRODUCT_COPY_FILES += \ # Camera PRODUCT_PACKAGES += \ + DubaiCameraService \ libgui_shim_vendor # Fingerprint