Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ class AACPManager {
identifier: ControlCommandIdentifiers, value: ByteArray
) {
val existingStatus = getControlCommandStatus(identifier)
if (existingStatus?.value.contentEquals(value)) {
if (existingStatus != null) {
controlCommandStatusList.remove(existingStatus)
}
controlCommandListeners[identifier]?.forEach { listener ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1462,6 +1462,7 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
preferences.getBoolean(key, true)

"head_gestures" -> config.headGestures = preferences.getBoolean(key, true)
"off_listening_mode" -> updateNoiseControlWidget()
"disconnect_when_not_wearing" -> config.disconnectWhenNotWearing =
preferences.getBoolean(key, false)

Expand Down Expand Up @@ -1957,54 +1958,97 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
val appWidgetManager = AppWidgetManager.getInstance(this)
val componentName = ComponentName(this, NoiseControlWidget::class.java)
val widgetIds = appWidgetManager.getAppWidgetIds(componentName)
val remoteViews = RemoteViews(packageName, R.layout.noise_control_widget).also { it ->
val ancStatus = ancNotification.status
val allowOffModeValue =
aacpManager.controlCommandStatusList.find { it.identifier == AACPManager.Companion.ControlCommandIdentifiers.ALLOW_OFF_OPTION }
val allowOffMode =
allowOffModeValue?.value?.takeIf { it.isNotEmpty() }?.get(0) == 0x01.toByte() || sharedPreferences.getBoolean("off_listening_mode", true)
it.setInt(
R.id.widget_off_button,
"setBackgroundResource",
if (ancStatus == 1) R.drawable.widget_button_checked_shape_start else R.drawable.widget_button_shape_start
)
it.setInt(
R.id.widget_transparency_button,
"setBackgroundResource",
if (ancStatus == 3) (if (allowOffMode) R.drawable.widget_button_checked_shape_middle else R.drawable.widget_button_checked_shape_start) else (if (allowOffMode) R.drawable.widget_button_shape_middle else R.drawable.widget_button_shape_start)
)
it.setInt(
R.id.widget_adaptive_button,
"setBackgroundResource",
if (ancStatus == 4) R.drawable.widget_button_checked_shape_middle else R.drawable.widget_button_shape_middle
)
it.setInt(
R.id.widget_anc_button,
"setBackgroundResource",
if (ancStatus == 2) R.drawable.widget_button_checked_shape_end else R.drawable.widget_button_shape_end
)
it.setViewVisibility(
R.id.widget_off_button, if (allowOffMode) View.VISIBLE else View.GONE
)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
it.setViewLayoutMargin(
R.id.widget_transparency_button,
RemoteViews.MARGIN_START,
if (allowOffMode) 2f else 12f,
TypedValue.COMPLEX_UNIT_DIP

val ancStatus = ancNotification.status
val allowOffModeValue =
aacpManager.controlCommandStatusList.find { it.identifier == AACPManager.Companion.ControlCommandIdentifiers.ALLOW_OFF_OPTION }
val allowOffMode =
allowOffModeValue?.value?.takeIf { it.isNotEmpty() }?.get(0) == 0x01.toByte() || sharedPreferences.getBoolean("off_listening_mode", true)

val visibleLabels = buildList {
if (allowOffMode) add(getString(R.string.off))
add(getString(R.string.transparency))
add(getString(R.string.adaptive))
add(getString(R.string.widget_noise_cancellation))
}

for (widgetId in widgetIds) {
val widgetWidthDp = appWidgetManager.getAppWidgetOptions(widgetId)
.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH, 180)
val uniformTextSizeSp = computeUniformWidgetTextSizeSp(widgetWidthDp, visibleLabels.size, visibleLabels)

val remoteViews = RemoteViews(packageName, R.layout.noise_control_widget).also { it ->
it.setInt(
R.id.widget_off_button,
"setBackgroundResource",
if (ancStatus == 1) R.drawable.widget_button_checked_shape_start else R.drawable.widget_button_shape_start
)
} else {
it.setViewPadding(
it.setInt(
R.id.widget_transparency_button,
if (allowOffMode) 2.dpToPx() else 12.dpToPx(),
12.dpToPx(),
2.dpToPx(),
12.dpToPx()
"setBackgroundResource",
if (ancStatus == 3) (if (allowOffMode) R.drawable.widget_button_checked_shape_middle else R.drawable.widget_button_checked_shape_start) else (if (allowOffMode) R.drawable.widget_button_shape_middle else R.drawable.widget_button_shape_start)
)
it.setInt(
R.id.widget_adaptive_button,
"setBackgroundResource",
if (ancStatus == 4) R.drawable.widget_button_checked_shape_middle else R.drawable.widget_button_shape_middle
)
it.setInt(
R.id.widget_anc_button,
"setBackgroundResource",
if (ancStatus == 2) R.drawable.widget_button_checked_shape_end else R.drawable.widget_button_shape_end
)
it.setViewVisibility(
R.id.widget_off_button, if (allowOffMode) View.VISIBLE else View.GONE
)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
it.setViewLayoutMargin(
R.id.widget_transparency_button,
RemoteViews.MARGIN_START,
if (allowOffMode) 2f else 12f,
TypedValue.COMPLEX_UNIT_DIP
)
} else {
it.setViewPadding(
R.id.widget_transparency_button,
if (allowOffMode) 2.dpToPx() else 12.dpToPx(),
12.dpToPx(),
2.dpToPx(),
12.dpToPx()
)
}
it.setTextViewTextSize(R.id.widget_off_button_label, TypedValue.COMPLEX_UNIT_SP, uniformTextSizeSp)
it.setTextViewTextSize(R.id.widget_transparency_button_label, TypedValue.COMPLEX_UNIT_SP, uniformTextSizeSp)
it.setTextViewTextSize(R.id.widget_adaptive_button_label, TypedValue.COMPLEX_UNIT_SP, uniformTextSizeSp)
it.setTextViewTextSize(R.id.widget_anc_button_label, TypedValue.COMPLEX_UNIT_SP, uniformTextSizeSp)
}

appWidgetManager.updateAppWidget(widgetId, remoteViews)
}
}

appWidgetManager.updateAppWidget(widgetIds, remoteViews)
private fun computeUniformWidgetTextSizeSp(
widgetWidthDp: Int,
buttonCount: Int,
labels: List<String>
): Float {
val displayMetrics = resources.displayMetrics
val widgetWidthPx = widgetWidthDp * displayMetrics.density
val outerMarginsPx = 24f * displayMetrics.density
val gapsPx = (buttonCount - 1) * 4f * displayMetrics.density
val perButtonPaddingPx = 8f * displayMetrics.density
val availablePerButtonPx = (widgetWidthPx - outerMarginsPx - gapsPx) / buttonCount - perButtonPaddingPx

val paint = android.text.TextPaint()
var size = 11f
while (size >= 7f) {
paint.textSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, size, displayMetrics)
if (labels.all { paint.measureText(it) <= availablePerButtonPx }) {
return size
}
size -= 0.5f
}
return 7f
}

@OptIn(ExperimentalMaterial3Api::class)
Expand Down
91 changes: 57 additions & 34 deletions android/app/src/main/res/layout/noise_control_widget.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,126 +18,149 @@
android:id="@+id/widget_off_button"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginVertical="12dp"
android:layout_marginVertical="6dp"
android:layout_marginStart="12dp"
android:layout_marginEnd="2dp"
android:layout_weight="1"
android:background="@drawable/widget_button_shape_start"
android:clickable="true"
android:gravity="center"
android:orientation="vertical">
android:orientation="vertical"
android:padding="4dp">

<ImageView
android:layout_width="52dp"
android:layout_height="52dp"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:src="@drawable/noise_cancellation"
android:tint="@color/white" />

<TextView
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:id="@+id/widget_off_button_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:gravity="center"
android:maxLines="1"
android:shadowColor="@color/black"
android:shadowRadius="12"
android:text="@string/off"
android:textColor="@color/white"
android:textSize="12sp" />
android:textSize="11sp" />
</LinearLayout>

<LinearLayout
android:id="@+id/widget_transparency_button"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginVertical="12dp"
android:layout_marginVertical="6dp"
android:layout_marginEnd="2dp"
android:layout_weight="1"
android:background="@drawable/widget_button_shape_middle"
android:clickable="true"
android:gravity="center"
android:orientation="vertical">
android:orientation="vertical"
android:padding="4dp">

<ImageView
android:layout_width="52dp"
android:layout_height="52dp"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:src="@drawable/transparency"
android:tint="@color/white" />

<TextView
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:id="@+id/widget_transparency_button_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:gravity="center"
android:maxLines="1"
android:shadowColor="@color/black"
android:shadowRadius="12"
android:text="@string/transparency"
android:textColor="@color/white"
android:textSize="12sp"
android:textSize="11sp"
tools:ignore="NestedWeights" />
</LinearLayout>

<LinearLayout
android:id="@+id/widget_adaptive_button"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginVertical="12dp"
android:layout_marginVertical="6dp"
android:layout_marginStart="2dp"
android:layout_marginEnd="2dp"
android:layout_weight="1"
android:background="@drawable/widget_button_shape_middle"
android:clickable="true"
android:gravity="center"
android:orientation="vertical">
android:orientation="vertical"
android:padding="4dp">

<ImageView
android:layout_width="52dp"
android:layout_height="52dp"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:src="@drawable/adaptive"
android:textSize="12sp"
android:tint="@color/white" />

<TextView
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:id="@+id/widget_adaptive_button_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:gravity="center"
android:maxLines="1"
android:shadowColor="@color/black"
android:shadowRadius="12"
android:text="@string/adaptive"
android:textColor="@color/white"
android:textSize="12sp"
android:textSize="11sp"
tools:ignore="NestedWeights" />
</LinearLayout>

<LinearLayout
android:id="@+id/widget_anc_button"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginVertical="12dp"
android:layout_marginVertical="6dp"
android:layout_marginStart="2dp"
android:layout_marginEnd="12dp"
android:layout_weight="1"
android:background="@drawable/widget_button_shape_end"
android:clickable="true"
android:gravity="center"
android:orientation="vertical">
android:orientation="vertical"
android:padding="4dp">

<ImageView
android:layout_width="52dp"
android:layout_height="52dp"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:src="@drawable/noise_cancellation"
android:tint="@color/white" />

<TextView
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:id="@+id/widget_anc_button_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:gravity="center"
android:maxLines="1"
android:shadowColor="@color/black"
android:shadowRadius="12"
android:text="@string/noise_cancellation"
android:text="@string/widget_noise_cancellation"
android:textColor="@color/white"
android:textSize="12sp"
android:textSize="11sp"
tools:ignore="NestedWeights" />
</LinearLayout>
</LinearLayout>
Expand Down
1 change: 1 addition & 0 deletions android/app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -267,4 +267,5 @@
<string name="app_enabled_in_xposed">App enabled in Xposed</string>
<string name="subject">Subject</string>
<string name="describe_your_issue">Describe your issue</string>
<string name="widget_noise_cancellation">ANC</string>
</resources>
Loading