Skip to content

Commit

Permalink
Set up workflow and fix formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
liamappelbe committed Dec 2, 2023
1 parent c0fc73f commit aed9ca9
Show file tree
Hide file tree
Showing 10 changed files with 1,260 additions and 1,172 deletions.
86 changes: 86 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Copyright 2023 The Deep Defender Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

name: CI

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
schedule:
- cron: "0 0 * * 0"

env:
PUB_ENVIRONMENT: bot.github

jobs:
analyze:
runs-on: ubuntu-latest
strategy:
matrix:
sdk: [ stable ]
steps:
- uses: actions/checkout@v3
- uses: subosito/flutter-action@v2
with:
channel: 'stable'
cache: true
- name: Install dependencies
id: install
run: flutter pub upgrade
- name: Check formatting
run: dart format --output=none --set-exit-if-changed .
if: always() && steps.install.outcome == 'success'
- name: Check analysis
run: flutter analyze --fatal-infos
if: always() && steps.install.outcome == 'success'

test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
sdk: [ stable, beta ]
steps:
- uses: actions/checkout@v3
- uses: subosito/flutter-action@v2
with:
channel: 'stable'
cache: true
- name: Install dependencies
run: flutter pub upgrade
- name: Run tests
run: flutter test

coverage:
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: subosito/flutter-action@v2
with:
channel: 'stable'
cache: true
- name: Install dependencies
run: flutter pub upgrade
- name: Install coverage
run: flutter pub global activate coverage
- name: Run tests and gather coverage
run: flutter pub global run coverage:test_with_coverage
- name: Upload coverage
uses: coverallsapp/github-action@v1.1.2
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
path-to-lcov: coverage/lcov.info
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
# Deep Defender

[![Build Status](https://github.com/liamappelbe/deep-defender/workflows/CI/badge.svg)](https://github.com/liamappelbe/deep-defender/actions?query=workflow%3ACI+branch%3Amain)
[![Coverage Status](https://coveralls.io/repos/github/liamappelbe/deep-defender/badge.svg?branch=main)](https://coveralls.io/github/liamappelbe/deep-defender?branch=main)

Real-time defense against deep fakes and malicious editing.

This is an experimental proof of concept app. No one should rely on this yet. I
Expand Down
39 changes: 12 additions & 27 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -1,29 +1,14 @@
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
# Copyright 2023 The Deep Defender Authors
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.

# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
include: package:flutter_lints/flutter.yaml

linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at
# https://dart-lang.github.io/linter/lints/index.html.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule

# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
8 changes: 5 additions & 3 deletions lib/debug_file.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,12 @@ class DebugFile {
static Future<void> save(Float64List audio, Uint8List safCode) async {
if (!DebugFile._enabled) return;
++_debugIndex;
final audioCopy = audio.sublist(0); // Make sure to copy before any awaits.
final audioCopy = audio.sublist(0); // Make sure to copy before any awaits.
final dir = await directory();
final filename = '${_debugIndex}_${base64Url.encode(safCode)}.wav';
final path = '$dir/$filename';
print("C:/Users/tiusic/AppData/Local/Android/Sdk/platform-tools/adb.exe pull $path $filename");
print(
"C:/Users/tiusic/AppData/Local/Android/Sdk/platform-tools/adb.exe pull $path $filename");
await Wav([audioCopy], kSampleRate).writeFile(path);
}

Expand All @@ -41,7 +42,8 @@ class DebugFile {
static Future<String> _directory() async {
final dir = (await getExternalStorageDirectories(
type: StorageDirectory.downloads,
))!.first;
))!
.first;
return (await dir.create(recursive: true)).path;
}
}
6 changes: 2 additions & 4 deletions lib/microphone.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ import 'const.dart';
import 'util.dart';

class Microphone {
static Future<Microphone?> mic(
void Function(int, MicData) callback) async {
static Future<Microphone?> mic(void Function(int, MicData) callback) async {
if (!(await Permission.microphone.request()).isGranted) {
return null;
}
Expand All @@ -35,8 +34,7 @@ class Microphone {
final void Function(int, MicData) _callback;
Microphone._(this._callback);

Future<void> _start() =>
_captor.start(
Future<void> _start() => _captor.start(
_onData,
print,
sampleRate: kSampleRate,
Expand Down
6 changes: 5 additions & 1 deletion lib/util.dart
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,11 @@ Uint64List logLinItr(int end, int steps, {double grad0 = 1}) {
return a;
}

double clamp(double x, double lo, double hi) => x < lo ? lo : x > hi ? hi : x;
double clamp(double x, double lo, double hi) => x < lo
? lo
: x > hi
? hi
: x;

void micDataToF64(MicData a, Float64List b) {
assert(b.length == a.length);
Expand Down
23 changes: 13 additions & 10 deletions lib/verifier.dart
Original file line number Diff line number Diff line change
Expand Up @@ -131,24 +131,27 @@ class SafCodeVerifier {
_timingEstimator.setTime(audioTimeSec, header.timeMs);

if (searchResult.score < hashCheck.minAllowedScore()) {
return VerifierResult(safCode, VerifierStatus.hashError, searchResult.score, header);
return VerifierResult(
safCode, VerifierStatus.hashError, searchResult.score, header);
}
final matchedAudio = hashCheck.getAudioSlice(searchResult.t)!;
final relativeLatency = audioTimeSec - (est.estAudioTimeSec ?? 0);
final speed = _timingEstimator.estimateSpeed;
final audioMatch = AudioMatch(
matchedAudio, audioTimeSec, relativeLatency, speed);
final audioMatch =
AudioMatch(matchedAudio, audioTimeSec, relativeLatency, speed);

// Check for speed errors.
if (speed < _minAllowedSpeed || speed > _maxAllowedSpeed) {
//print("Speed error: $speed");
return VerifierResult(safCode, VerifierStatus.speedError, searchResult.score, header);
return VerifierResult(
safCode, VerifierStatus.speedError, searchResult.score, header);
}

// TODO(#4): Drop data from the audio buffer and update the audio index.

// Report result.
return VerifierResult(safCode, VerifierStatus.ok, searchResult.score, header, audioMatch);
return VerifierResult(
safCode, VerifierStatus.ok, searchResult.score, header, audioMatch);
}

int get _minAudioCodeSize {
Expand Down Expand Up @@ -264,8 +267,8 @@ class _HashCheck {
// TODO(#8): Verify the volume.
//if (a.length != b.length) return -1;
assert(a.length == b.length);
final volume = Hasher.u32ToVol(
ByteData.sublistView(a).getUint32(0, Endian.big));
final volume =
Hasher.u32ToVol(ByteData.sublistView(a).getUint32(0, Endian.big));
int sum = 0;
for (int i = 4; i < a.length; ++i) {
sum += _bitCountUint8(0xFF & ~(a[i] ^ b[i]));
Expand Down Expand Up @@ -336,7 +339,8 @@ class VerifierResult {
// Present only if error is ok or speedError
final AudioMatch? audio;

VerifierResult(this.safCode, this.error, this.score, [this.header, this.audio]);
VerifierResult(this.safCode, this.error, this.score,
[this.header, this.audio]);

String toString() => error.toString();
}
Expand Down Expand Up @@ -373,8 +377,7 @@ class _TimingEstimate {
double? estAudioTimeSec;
double? targetAudioTimeSec;
double maxAudioTimeSec;
_TimingEstimate(
this.minAudioTimeSec, this.estAudioTimeSec,
_TimingEstimate(this.minAudioTimeSec, this.estAudioTimeSec,
this.targetAudioTimeSec, this.maxAudioTimeSec);
String toString() => '{$minAudioTimeSec, $estAudioTimeSec, $maxAudioTimeSec}';
}
Expand Down
Loading

0 comments on commit aed9ca9

Please sign in to comment.