Files
arc/.planning/codebase/CONVENTIONS.md
2026-03-30 15:21:07 +08:00

6.3 KiB
Raw Permalink Blame History

Coding Conventions

Analysis Date: 2026-03-30

Naming Patterns

Files:

  • Dart: lowercase with underscores (arc.dart, arc_platform_interface.dart, arc_method_channel.dart)
  • Java: PascalCase matching class name (ArcPlugin.java, FaceEngineManager.java)

Classes:

  • PascalCase: Arc, ArcPlatform, MethodChannelArc, FaceEngineManager, FaceErrorCode

Methods/Functions:

  • camelCase: getPlatformVersion, activeOnline, detectFaces, extractFaceFeature

Variables:

  • Private Dart members: underscore prefix (_token, _instance, _isDetecting)
  • Java: private keyword with camelCase: faceEngine, isInitialized, lastRgbLiveness

Constants:

  • Dart: static final with underscore for private: static final Object _token = Object();
  • Java enum: uppercase with underscores: MOK, MERR_UNKNOWN, ENGINE_NOT_INITIALIZED

Code Style

Formatting:

  • Dart: flutter_lints ^5.0.0 via analysis_options.yaml
  • Config: include: package:flutter_lints/flutter.yaml
  • Java: Standard Android/Java conventions

Linting:

  • Dart: flutter_lints package rules
  • Java: No explicit linting config detected

Import Organization

Dart Order:

  1. SDK imports (dart:typed_data)
  2. Package imports (package:plugin_platform_interface/plugin_platform_interface.dart)
  3. Relative imports (arc_method_channel.dart)

Example:

import 'dart:typed_data';

import 'package:plugin_platform_interface/plugin_platform_interface.dart';

import 'arc_method_channel.dart';

Java Order:

  1. Package declaration
  2. Android SDK imports
  3. Third-party imports
  4. JUnit/Mockito imports (in tests)

Error Handling

Dart Patterns:

  • Platform interface throws UnimplementedError for abstract methods:
Future<String?> getPlatformVersion() {
  throw UnimplementedError('platformVersion() has not been implemented.');
}
  • Method channel calls wrapped in try-catch with PlatformException
  • Return Map<String, dynamic>? with success, errorCode, message keys

Java Patterns:

  • Parameter validation before processing
  • Error codes via FaceErrorCode enum
  • Result Map with consistent keys: success, errorCode, message
  • Logging with android.util.Log.e() for errors

Return Format: All API methods return consistent Map structure:

{
  'success': bool,      // Operation success status
  'errorCode': int,     // Error code (0 = success)
  'message': String,    // Error/success message
  // Additional data keys based on method
}

Documentation

Dart Comments:

  • Triple-slash /// for method documentation
  • Chinese descriptions required
  • Parameter documentation: [paramName] description
  • Return documentation after parameters

Example:

/// 激活 SDK在线激活
/// [appId] 应用 ID从虹软控制台获取
/// [sdkKey] SDK 密钥(从虹软控制台获取)
/// [activeKey] 激活密钥
/// 返回包含 success, errorCode, message 的 Map
Future<Map<String, dynamic>?> activeOnline({
  required String appId,
  required String sdkKey,
  required String activeKey,
})

Java Comments:

  • Javadoc /** */ format
  • @param and @return tags
  • Chinese descriptions

Example:

/**
 * 激活 SDK在线激活方式
 * @param context Android 上下文
 * @param appId 应用 ID从虹软控制台获取
 * @param sdkKey SDK 密钥(从虹软控制台获取)
 * @param activeKey 激活密钥
 * @return 错误码0 表示成功)
 */
public int activeOnline(Context context, String appId, String sdkKey, String activeKey)

Logging

Dart:

  • debugPrint() for development logging
  • Located in: example/lib/main.dart

Java:

  • android.util.Log.i() for info
  • android.util.Log.e() for errors
  • android.util.Log.w() for warnings
  • Tag: "FaceEngineManager"

Example:

android.util.Log.i("FaceEngineManager", "引擎初始化成功!");
android.util.Log.e("FaceEngineManager", "引擎初始化失败,错误码: " + result);

Function Design

Parameters:

  • Dart: Named parameters with required keyword
  • Optional parameters have default values

Example:

Future<Map<String, dynamic>?> detectFaces({
  required Uint8List data,
  required int width,
  required int height,
  int format = 2050,  // Optional with default
})

Return Values:

  • All async methods return Future<Map<String, dynamic>?>
  • Null-safe with nullable type annotation ?

Module Design

Platform Interface Pattern:

  • Abstract class extends PlatformInterface
  • Static instance getter/setter
  • Token verification for platform registration

Example Structure:

abstract class ArcPlatform extends PlatformInterface {
  ArcPlatform() : super(token: _token);
  static final Object _token = Object();
  static ArcPlatform _instance = MethodChannelArc();
  static ArcPlatform get instance => _instance;
  static set instance(ArcPlatform instance) {
    PlatformInterface.verifyToken(instance, _token);
    _instance = instance;
  }
}

Method Channel Implementation:

  • Class extends platform interface
  • @visibleForTesting annotation for test exposure
  • Method channel with constant name: 'arc'

Singleton Pattern (Java):

public class FaceEngineManager {
    private static FaceEngineManager instance;
    private FaceEngineManager() {}
    public static synchronized FaceEngineManager getInstance() {
        if (instance == null) {
            instance = new FaceEngineManager();
        }
        return instance;
    }
}

State Management

Flutter Widget State:

  • Private state variables with underscore prefix
  • StatefulWidget with corresponding State class
  • mounted check before setState

Example:

class _HomePageState extends State<HomePage> {
  String _platformVersion = 'Unknown';
  bool _isActivated = false;

  if (!mounted) return;
  setState(() {
    _platformVersion = platformVersion;
  });
}

Key Files

Core Dart Files:

  • lib/arc.dart - Main API class
  • lib/arc_platform_interface.dart - Abstract platform interface
  • lib/arc_method_channel.dart - Method channel implementation

Core Java Files:

  • android/src/main/java/com/xiarui/arc/ArcPlugin.java - Flutter plugin entry
  • android/src/main/java/com/xiarui/arc/FaceEngineManager.java - Engine singleton
  • android/src/main/java/com/xiarui/arc/FaceErrorCode.java - Error code enum

Convention analysis: 2026-03-30