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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Built application files
*.apk
*.aar
!app/libs/BluetoothBinding.aar
*.ap_
*.aab

Expand Down
5 changes: 3 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ android {
applicationId "com.sunmi.printerconfig"
minSdk 21
targetSdk 35
versionCode 2
versionName "1.0.1"
versionCode 11
versionName "1.0.10"
}

signingConfigs {
Expand Down Expand Up @@ -56,6 +56,7 @@ android {
}

dependencies {
implementation files('libs/BluetoothBinding.aar')
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# 1) Verify artifact exists
if [ -f app/libs/BluetoothBinding.aar ]; then
  echo "✓ File exists: app/libs/BluetoothBinding.aar"
  # 2) Produce deterministic digest to pin in CI/docs
  sha256sum app/libs/BluetoothBinding.aar
else
  echo "✗ File NOT found: app/libs/BluetoothBinding.aar"
fi

# 3) Confirm local AAR usage points
echo ""
echo "Searching for local AAR references in build files:"
rg -n "implementation\s+files\('libs/.*\.aar" --type gradle

Repository: Arieboomsma/connectprinter

Length of output: 181


🏁 Script executed:

# Check for CI configuration that might validate dependencies
echo "Checking for CI/CD configuration:"
find . -type f \( -name ".github" -o -name ".gitlab-ci.yml" -o -name "*.yml" -o -name "*.yaml" \) -o -path "*/.github/workflows/*" | head -20

# Look for any checksum or integrity validation docs
echo ""
echo "Searching for provenance/checksum documentation:"
rg -i "checksum|sha256|integrity|provenance|BluetoothBinding" --type md --type txt

Repository: Arieboomsma/connectprinter

Length of output: 153


🏁 Script executed:

# Check if there are any gradle dependency verification mechanisms
echo "Checking for gradle dependency verification:"
cat -n gradle/verification-metadata.xml 2>/dev/null || echo "No verification-metadata.xml found"

# Check build.gradle structure for other dependency management
echo ""
echo "Full app/build.gradle to understand context:"
cat -n app/build.gradle | head -80

Repository: Arieboomsma/connectprinter

Length of output: 2415


🏁 Script executed:

# Search for any documentation or context about BluetoothBinding
echo "Searching for BluetoothBinding references:"
rg -i "bluetooth" --type md --type txt --type java --type kt

# Check for README or documentation
echo ""
echo "Checking for README or documentation:"
find . -maxdepth 2 -type f \( -name "README*" -o -name "*.md" \)

Repository: Arieboomsma/connectprinter

Length of output: 268


🏁 Script executed:

# Check git history to understand when and why this was added
echo "Checking file existence and context:"
ls -lh app/libs/BluetoothBinding.aar 2>/dev/null || echo "File details unavailable"

# Look for any build documentation
echo ""
echo "Build/dependency documentation:"
find . -maxdepth 2 -type f -name "*build*" -o -name "*DEPEND*" -o -name "*.md"

Repository: Arieboomsma/connectprinter

Length of output: 336


🏁 Script executed:

# Check README for dependency context
echo "=== README.md ==="
cat README.md

echo ""
echo "=== QUICK_START.md ==="
cat QUICK_START.md

Repository: Arieboomsma/connectprinter

Length of output: 10807


🏁 Script executed:

# Check build.sh for any validation or checksum logic
echo "=== build.sh ==="
cat build.sh

# Check root build.gradle for dependency management
echo ""
echo "=== root build.gradle ==="
cat build.gradle

Repository: Arieboomsma/connectprinter

Length of output: 2008


Pin the BluetoothBinding.aar artifact hash in CI to verify supply-chain integrity.

The local BluetoothBinding.aar dependency bypasses Maven metadata and weakens supply-chain visibility. Add a SHA-256 verification step in your CI/CD pipeline to ensure the artifact hasn't been tampered with. If this is a vendor-supplied library, document its origin and source in the repository (CONTRIBUTING.md or build README).

No existing verification mechanisms (gradle verification-metadata.xml, CI checks) were found.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/build.gradle` at line 59, The dependency declaration implementation
files('libs/BluetoothBinding.aar') should be protected by pinning its SHA-256
and documenting its origin; update CI to compute and verify the artifact's
SHA-256 before build (reject if mismatch) and add the expected hex hash to the
CI job or a repository file, and also add vendor/source and download provenance
for BluetoothBinding.aar to CONTRIBUTING.md or the build README; alternatively,
generate/commit a gradle verification-metadata.xml entry for
BluetoothBinding.aar and have CI validate it prior to invoking the Gradle build.

implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.11.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
Expand Down
Binary file added app/libs/BluetoothBinding.aar
Binary file not shown.
9 changes: 9 additions & 0 deletions app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,12 @@

# Keep printer configuration classes
-keep class com.sunmi.printerconfig.** { *; }

# Keep Sunmi SDK callback interfaces/classes used during Wi-Fi configuration.
-keep class com.sunmi.cloudprinter.** { *; }
-keep interface com.sunmi.cloudprinter.** { *; }

# Keep callback implementers and SDK internals that may be invoked reflectively.
-keep class * implements com.sunmi.cloudprinter.presenter.SunmiPrinterClient$IPrinterClient { *; }
-keep class library.** { *; }
-keep class com.inuker.bluetooth.library.** { *; }
5 changes: 4 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@

<!-- Needed for Bluetooth discovery on Android 6-11 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, locate and examine the AndroidManifest.xml file
find . -name "AndroidManifest.xml" -type f

Repository: Arieboomsma/connectprinter

Length of output: 104


🏁 Script executed:

# Check the content of the file around lines 16-23
if [ -f "app/src/main/AndroidManifest.xml" ]; then
  echo "=== Current AndroidManifest.xml (lines 1-35) ==="
  head -35 "app/src/main/AndroidManifest.xml" | cat -n
fi

Repository: Arieboomsma/connectprinter

Length of output: 2023


🏁 Script executed:

# Check git history for this file to see what changed
cd . && git log --oneline -10 -- "app/src/main/AndroidManifest.xml" 2>/dev/null || echo "Git history not available"

Repository: Arieboomsma/connectprinter

Length of output: 142


🏁 Script executed:

# Try to see the diff for the most recent change to this file
git diff HEAD~1 HEAD -- "app/src/main/AndroidManifest.xml" 2>/dev/null || echo "Cannot get git diff"

Repository: Arieboomsma/connectprinter

Length of output: 89


🏁 Script executed:

# Try to get the full git log with patch to see if maxSdkVersion was removed
git log -p --all -- "app/src/main/AndroidManifest.xml" 2>/dev/null | grep -A5 -B5 "ACCESS_FINE_LOCATION" | head -50 || echo "Cannot retrieve full history"

Repository: Arieboomsma/connectprinter

Length of output: 52


🏁 Script executed:

# Check if there are any recent commits that mention this change
git log --all --oneline -20 2>/dev/null || echo "Git not available"

Repository: Arieboomsma/connectprinter

Length of output: 599


🏁 Script executed:

# Search for any issues or comments in the code about location permissions
rg "ACCESS_FINE_LOCATION|maxSdkVersion.*30" --type xml -B2 -A2

Repository: Arieboomsma/connectprinter

Length of output: 1077


Scope ACCESS_FINE_LOCATION to Android 11 and earlier.

Line 16 declares precise location permission without API level constraints, but the comment on line 14 explicitly states this is needed only for "Bluetooth discovery on Android 6-11." The parallel permission on line 15 (ACCESS_COARSE_LOCATION) is correctly scoped to maxSdkVersion="30" for the same feature. On Android 12+, the app uses NEARBY_WIFI_DEVICES with neverForLocation flag, making ACCESS_FINE_LOCATION unnecessary. Leaving it unscoped unnecessarily broadens the privacy/compliance scope on modern Android versions.

🔧 Suggested fix
-    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+    <uses-permission
+        android:name="android.permission.ACCESS_FINE_LOCATION"
+        android:maxSdkVersion="30" />
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION"
android:maxSdkVersion="30" />
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/src/main/AndroidManifest.xml` at line 16, Scope the ACCESS_FINE_LOCATION
permission to Android 11 and earlier by adding maxSdkVersion="30" to the
uses-permission element named android.permission.ACCESS_FINE_LOCATION; locate
the uses-permission with android:name="android.permission.ACCESS_FINE_LOCATION"
and update it to mirror the ACCESS_COARSE_LOCATION entry (which uses
maxSdkVersion="30") so the precise location permission is not requested on
Android 12+ where NEARBY_WIFI_DEVICES with neverForLocation is used.


<!-- Wi-Fi permissions -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission
android:name="android.permission.NEARBY_WIFI_DEVICES"
android:usesPermissionFlags="neverForLocation" />

<!-- Internet permission -->
<uses-permission android:name="android.permission.INTERNET" />
Expand Down
38 changes: 38 additions & 0 deletions app/src/main/java/com/sunmi/printerconfig/DiscoveredPrinter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.sunmi.printerconfig;

import java.util.Objects;

public final class DiscoveredPrinter {
private final String address;
private final String name;

public DiscoveredPrinter(String address, String name) {
this.address = address == null ? "" : address.trim();
this.name = name == null ? "" : name.trim();
}

public String getAddress() {
return address;
}

public String getName() {
return name;
}

@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof DiscoveredPrinter)) {
return false;
}
DiscoveredPrinter that = (DiscoveredPrinter) other;
return Objects.equals(address, that.address);
}

@Override
public int hashCode() {
return Objects.hash(address);
}
}
Original file line number Diff line number Diff line change
@@ -1,29 +1,24 @@
package com.sunmi.printerconfig;

import android.Manifest;
import android.bluetooth.BluetoothDevice;
import android.content.pm.PackageManager;
import android.os.Build;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;

import java.util.List;

public class BluetoothDeviceAdapter extends RecyclerView.Adapter<BluetoothDeviceAdapter.ViewHolder> {
private final List<BluetoothDevice> devices;
public class DiscoveredPrinterAdapter extends RecyclerView.Adapter<DiscoveredPrinterAdapter.ViewHolder> {
private final List<DiscoveredPrinter> devices;
private final OnDeviceClickListener listener;

public interface OnDeviceClickListener {
void onDeviceClick(BluetoothDevice device);
void onDeviceClick(DiscoveredPrinter device);
}

public BluetoothDeviceAdapter(List<BluetoothDevice> devices, OnDeviceClickListener listener) {
public DiscoveredPrinterAdapter(List<DiscoveredPrinter> devices, OnDeviceClickListener listener) {
this.devices = devices;
this.listener = listener;
}
Expand All @@ -38,24 +33,18 @@ public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
BluetoothDevice device = devices.get(position);
boolean hasPermission = true;
DiscoveredPrinter device = devices.get(position);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
hasPermission = ContextCompat.checkSelfPermission(holder.itemView.getContext(),
Manifest.permission.BLUETOOTH_CONNECT) == PackageManager.PERMISSION_GRANTED;
}
String baseName = device.getName().isEmpty()
? holder.itemView.getContext().getString(R.string.unknown_device)
: device.getName();

if (hasPermission) {
String name = device.getName();
String address = device.getAddress();
holder.deviceName.setText(name != null ? name : "Unknown Device");
holder.deviceAddress.setText(address);
} else {
holder.deviceName.setText("Permission Required");
holder.deviceAddress.setText("");
if (PrinterDeviceClassifier.isLikelySunmi(device.getName())) {
baseName = baseName + " \u2022 " + holder.itemView.getContext().getString(R.string.likely_sunmi);
}

holder.deviceName.setText(baseName);
holder.deviceAddress.setText(device.getAddress());
holder.itemView.setOnClickListener(v -> listener.onDeviceClick(device));
}

Expand All @@ -65,8 +54,8 @@ public int getItemCount() {
}

static class ViewHolder extends RecyclerView.ViewHolder {
TextView deviceName;
TextView deviceAddress;
private final TextView deviceName;
private final TextView deviceAddress;

ViewHolder(View itemView) {
super(itemView);
Expand Down
Loading