keiji / chino Goto Github PK
View Code? Open in Web Editor NEWCappuccino is an yet another Exposure Notification Library for COCOA.
License: Other
Cappuccino is an yet another Exposure Notification Library for COCOA.
License: Other
Prism(Xamarin.Forms)での利用サンプルを作成した中で気づいた不明瞭なChinoのAPIを調整する。
Chino.iOSとしてShared
を持つ必要はない。必要な場合はiOSプロジェクト側で持てば足りる。
chino/Chino.iOS/ExposureNotificationClient.cs
Lines 17 to 19 in 01558fc
Init忘れの時にエラーメッセージを表示して欲しい。
chino/Chino.iOS/ExposureNotificationClient.cs
Lines 39 to 47 in 01558fc
Handlerの設定とInitを同時にした方がわかりやすいので検討する。← BroadcastReceiverからアクセスする方法がないのでこのままにする。
Loggerはよくある名前と衝突するのでライブラリの外に出したくない(スコープを狭める?)。← スコープを狭めるとChino.Android/iOSからも使えないので名前をChinoLoggerに変える。
async
付けたメソッドは名前の末尾にAsync
を付けるべき。
ユーザー承認待ちのケースでTEKが0件変える時にも、ID計算のために0件のリストをLINQ(Max)で処理しようとしているのが原因。
chino/Sample.Common/Model/TemporaryExposureKeys.cs
Lines 52 to 56 in 2334093
System.InvalidOperationException: Sequence contains no elements
at System.Linq.Enumerable.Max[TSource] (System.Collections.Generic.IEnumerable`1[T] source, System.Func`2[T,TResult] selector) [0x0002b] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/external/corefx/src/System.Linq/src/System/Linq/Max.cs:620
at Sample.Common.Model.TemporaryExposureKeys.UpdateId () [0x00001] in /Volumes/MHLW/repos/Chino/Sample.Common/Model/TemporaryExposureKeys.cs:54
at Sample.Common.Model.TemporaryExposureKeys..ctor (System.Collections.Generic.IList`1[T] teks, System.DateTime generatedAt, Chino.ReportType defaultRportType, Chino.RiskLevel defaultTrasmissionRisk) [0x00057] in /Volumes/MHLW/repos/Chino/Sample.Common/Model/TemporaryExposureKeys.cs:49
at Sample.Android.MainActivity.SaveTekHistoryAsync (System.Collections.Generic.List`1[T] temporaryExposureKeys) [0x00013] in /Volumes/MHLW/repos/Chino/Sample.Android/MainActivity.cs:219
at Sample.Android.MainActivity.<OnCreate>b__14_1 (System.Object <p0>, System.EventArgs <p1>) [0x000cb] in /Volumes/MHLW/repos/Chino/Sample.Android/MainActivity.cs:72
at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__7_0 (System.Object state) [0x00000] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:1021
at Android.App.SyncContext+<>c__DisplayClass2_0.<Post>b__0 () [0x00000] in /Users/builder/azdo/_work/2/s/xamarin-android/src/Mono.Android/Android.App/SyncContext.cs:36
at Java.Lang.Thread+RunnableImplementor.Run () [0x00008] in /Users/builder/azdo/_work/2/s/xamarin-android/src/Mono.Android/Java.Lang/Thread.cs:36
at Java.Lang.IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this) [0x00008] in /Users/builder/azdo/_work/2/s/xamarin-android/src/Mono.Android/obj/Release/monoandroid10/android-30/mcw/Java.Lang.IRunnable.cs:90
at at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.31(intptr,intptr)
現在のCappuccinoは、iOS版のGetDiagnosisKeysAsync
とGetTestDiagnosisKeysAsync
の呼び分けをIsTest
の設定によって切り替えている。
chino/Chino.iOS/ExposureNotificationClient.cs
Lines 184 to 193 in f290e49
しかしこの方法ではバイナリ中にGetTestDiagnosisKeysAsync
の呼び出し経路が残った状態になるため、接触確認アプリのリリース審査で指摘を受ける可能性がCOCOA開発チームから示されている。
審査を円滑に進めるため、IsTestによる呼び分けを廃止して、ビルド構成Release・Debugによる呼び分けに変更する。
CappuccinoのバイナリをDebug/Release両方を提供して、ビルド時にどちらのnuget packageを利用するか切り替えできるようにする。
ソリューションを作ったときに packages.config
が作成されているが、現在はへの移行が案内されているので検討する。
packages.config から PackageReference への移行
https://docs.microsoft.com/ja-jp/nuget/consume-packages/migrate-packages-config-to-package-reference
EN APIの状態(Status)がAndroid, iOSで定義が異なるので吸収する仕組みが必要。
https://developers.google.com/android/reference/com/google/android/gms/nearby/exposurenotification/ExposureNotificationStatus
https://developer.apple.com/documentation/exposurenotification/enstatus
publicなAPIにコメントを付けること
オープンソースのライセンスを決める必要がある。
COCOAのライセンスが MPL(Mozilla Public License)2.0 なので、それと互換性があるものにする。
候補としては、
COPYRIGHT HOLDER はCappuccino Authors
としたい。
LICENSE
としてリポジトリに追加されることLicense
の項目を設けて、必要な記述を終えること#2 で検討した結果(packages.configはもうメンテナンスされていないため)、PackageReferenceに移行する。
ExposureConfiguration
をJSONで取り扱えるようにしたい。
LICENSE
にJSONライブラリのエントリを記入することExposureConfiguration
にJSONキーを設定してシリアライズ、デシリアライズができることExposureNotificationClient#setDiagnosisKeysDataMapping
は週 1 回という呼び出し回数の制限があります。
週 2 回以上呼び出すとステータスコードFAILED_RATE_LIMITED
の例外がスローされるようです。
https://developers.google.com/android/reference/com/google/android/gms/nearby/exposurenotification/ExposureNotificationClient#setDiagnosisKeysDataMapping(com.google.android.gms.nearby.exposurenotification.DiagnosisKeysDataMapping)
Chino.Android の当該箇所
例えば Google のサンプルでは、前回のマップと比較して同じならばsetDiagnosisKeysDataMapping
を呼び出さない、ということをしています。
https://github.com/google/exposure-notifications-android/blob/610788eb3815d8ddb397332ba6f982308f7cde01/app/src/main/java/com/google/android/apps/exposurenotification/nearby/ProvideDiagnosisKeysWorker.java#L182
Fhi.Smittestopp.App では、前回呼び出し時刻を保持しておいて、7 日以内であれば何もしない、ということをしています。
https://github.com/folkehelseinstituttet/Fhi.Smittestopp.App/blob/7c8e687a24d7e9d0f27f0885ee6d48d8a2c2e41e/NDB.Covid19/NDB.Covid19.Droid/Utils/BackgroundFetchScheduler.cs#L100
https://github.com/folkehelseinstituttet/Fhi.Smittestopp.App/blob/7c8e687a24d7e9d0f27f0885ee6d48d8a2c2e41e/NDB.Covid19/NDB.Covid19.Droid/Utils/DiagnosisKeysDataMappingUtils.cs#L42
ちなみに、iOS においても、同様のマップは週 1 回しか更新できないようです
https://developer.apple.com/documentation/exposurenotification/enexposureconfiguration/3644389-infectiousnessfordayssinceonseto
You can’t change this property more often than once per week. During development, you can remove this limitation by adding the test entitlement com.apple.developer.exposure-notification-test to your project.
が、こちらは 2 回更新したときにエラーになるのか無視されるのか、どのような振舞いになるのかはドキュメントから見つけることができませんでした。
https://github.com/keiji/chino/wiki/Sample-ExposureData-Android-(Exposure-Window-mode)
Androidから得られるDailySummaryのDateMillisSinceEpochの値にマイナス値が見受けられる。Epochからのミリ秒という定義からするとおかしいので、変換が間違っている可能性がある。
iOSと照合して、必要に応じて修正する。
Legacy-v1(ENv1)固有の事象のためCOCOA2への影響はない。
事象としては #36 と同様。
ExposureSummaryのgetAttenuationDurationsInMinutes
およびattenuationDurations
が、iOSでは「秒単位」であるのに対して、Androidでは「分単位」と定義が異なる。
ExposureInformation
https://developers.google.com/android/reference/com/google/android/gms/nearby/exposurenotification/ExposureSummary#getAttenuationDurationsInMinutes()
ENExposureDetectionSummary.attenuationDurations
https://developer.apple.com/documentation/exposurenotification/enexposuredetectionsummary/3586985-attenuationdurations
An array that contains the duration, in seconds, at certain attenuations, using an aggregated maximum exposures of 30 minutes.
これらの違いを吸収する仕組みが現在のchinoに実装されておらず、iOSではAttenuationDurationsInMinutes
と言う変数名で値を取得しているので、接触確認後の処理が共通化できない。
Android版
"exposure_summary": {
"AttenuationDurationsInMinutes": [
30,
0,
0
],
iOS版
"exposure_summary": {
"AttenuationDurationsInMinutes": [
1800,
1560,
0
],
ExposureStateBroadcastReceiver について、OnReceive
内で呼び出している各タスクはOnReceive
を抜けた後も処理を続けることになるのだと思うのですが、 その場合以下にあるようにシステムによってアプリプロセスを終了させられてしまう可能性があるのではないかと思います。
(見落としならばすみません)
https://developer.android.com/guide/components/broadcasts?hl=ja#effects-process-state
例えば Google のサンプルでは、WorkManager を使っています。
https://github.com/google/exposure-notifications-android/blob/610788eb3815d8ddb397332ba6f982308f7cde01/app/src/main/java/com/google/android/apps/exposurenotification/nearby/ExposureNotificationBroadcastReceiver.java#L66
https://github.com/google/exposure-notifications-android/blob/610788eb3815d8ddb397332ba6f982308f7cde01/app/src/main/java/com/google/android/apps/exposurenotification/nearby/StateUpdatedWorker.java#L117
Xamarin.ExposureNotification
では JobIntentService にまかせています。
https://github.com/xamarin/XamarinComponents/blob/e5ac2d06c8b6b2904ff119d8bae8b1d5e7cb2127/XPlat/ExposureNotification/source/Xamarin.ExposureNotification/CallbackService.android.cs#L28
https://github.com/xamarin/XamarinComponents/blob/main/XPlat/ExposureNotification/source/Xamarin.ExposureNotification/CallbackService.android.cs#L39
ExposureNotification API(iOS)は、iOSのバージョンについてよって使えるAPIが異なる。
最終的にアプリ側で分岐することになるが、その判断基準となる対応バージョン情報をAPI側に記載する必要がある。
privateなメンバ変数は _ 始まりに統一する。
Breaking Changeは発生しない。
msbuild
? dotnet
?)#77 に関連して、DiagnosisKeysDataMappingは一度設定すると1週間以上空けないといけないので、最終更新日時を保存するために更新のタイミングをコールバックで受け取る必要がある。
https://github.com/cocoa-mhlw/cocoa/pull/482/files#r748175954
現在はChino.Common.Tests
を整備しているが、これに各プラットフォーム固有の機能をテストできるChino.Android.Tests
, Chino.iOS.Tests
を追加する。
iOSのENDetectionSummary
、ENv2ではENExposureInfo
同様、Deprecatedになったと思っていたらDeprecatedではなかった。
https://developer.apple.com/documentation/exposurenotification/enexposuredetectionsummary
だとするとENv2のiOSについてはENDetectionSummary
もHandlerを通じて返すようにした方がいい。
言語設定の変更など端末の状態が大きく変わるタイミングでGoogle Play Servicesが再初期化され、そのタイミングでGoogle Play Servicesに接続しようとするとApiExceptionがthrowされる。
そのstatusCodeは8 InternalError
であったり20 ConnectionSuspendedDuringCall
であったりするが、今のCappuccinoはそれらのStatusはENExceptionの変換対象ではないので、そのままApiExceptionとしてthrowしてしまう。
ExposureInformation.Durationの値が、Googleは分単位なのに対してAppleは秒単位。
chino/Chino.Common/ExposureInformation.cs
Lines 28 to 31 in 31228a8
Length of exposure in 5 minute increments, with a 30 minute maximum.
Apple
https://developer.apple.com/documentation/exposurenotification/enexposureinfo/3583714-duration
When reporting the duration of an exposure, the values are stored as seconds rounded up to the next minute. A duration value caps at 30 minutes (1800 seconds).
増分は5分に当たる値。最大値は30分に当たる値であることは共通している。
現在は未調整なので、プラットフォームプロジェクト側で値の調整をする必要がある。
Android
"exposure_informations": [
{
"AttenuationDurationsInMillis": [
0,
27000000,
0
],
"AttenuationValue": 55,
"DateMillisSinceEpoch": 1627344000000,
"Duration": 30.0,
"TotalRiskScore": 256,
"TransmissionRiskLevel": 4
},
iOS
"exposure_informations": [
{
"AttenuationDurationsInMillis": [
1800000,
0,
0,
0
],
"AttenuationValue": 5,
"DateMillisSinceEpoch": 1627084800000,
"Duration": 1800.0,
"TotalRiskScore": 200,
"TransmissionRiskLevel": 4
},
エラー発生時にApiException
, ENError
などで返される情報を吸収する仕組みが必要。
https://developer.apple.com/documentation/exposurenotification/enerror
作り始めたときは同じ名前空間(Chino
)の方が都合が良いと思っていたけど、Chino.Prismとかまで行くと同じにする意味はなかったのでわかりやすくする。
実際にCOCOAに組み込んでみて、コールバックの中でいちいちTaskを作って非同期処理を開始しているので、だったらCappuccinoの時点でasyncを前提にした方がいいよねという話。
ExposureInformationのAttenuationDurations
およびAttenuationDurations
が、iOSでは「秒単位」であるのに対して、Androidでは「分単位」と定義が異なる。
ExposureInformation
https://developers.google.com/android/reference/com/google/android/gms/nearby/exposurenotification/ExposureInformation
ENExposureInfo.attenuationDurations
https://developer.apple.com/documentation/exposurenotification/enexposureinfo
An array that contains the duration, in seconds, at certain attenuations, using an aggregated maximum exposures of 30 minutes.
これらの違いを吸収する仕組みが現在のchinoに実装されておらず、iOSではInMinutes
と言う変数名で値を取得しているので、接触確認後の処理が共通化できない。
Android版
chino/Chino.Android/ExposureInformation.cs
Lines 18 to 20 in 698eb4f
"exposure_informations": [
{
"AttenuationDurationsInMinutes": [
1436,
0,
0
],
"AttenuationValue": 26,
"DateMillisSinceEpoch": 1622851200000,
"Duration": 30.0,
"TotalRiskScore": 256,
"TransmissionRiskLevel": 4
},
iOS版
chino/Chino.iOS/ExposureInformation.cs
Lines 17 to 19 in 698eb4f
"exposure_informations": [
{
"AttenuationDurationsInMinutes": [
1800,
0,
0,
0
],
"AttenuationValue": 4,
"DateMillisSinceEpoch": 1622764800000,
"Duration": 1800.0,
"TotalRiskScore": 255,
"TransmissionRiskLevel": 4
},
ビルドチェックやテストをGitHub Actionsを使って行う。
minimum_risk_score
ではなくminimum_window_score
の方が良い。
chino/Chino.Common/DailySummariesConfig.cs
Lines 51 to 52 in 698eb4f
Legacy V1 modeで動作させた際、ExposureNotificationClient
にExposureConfiguration
を保持する処理がないため、接触確認結果のJSONファイルに接触判定の設定が含まれない。
ExposureWindow
, DailySummary
, ExposureInformation
, ExposureSummary
などのクラスについてEquals
とGetHashCode
メソッドが整備されていない。
現在、CIでCommon.Testsのユニットテストを実行しているが、加えてAndroidとiOSでのビルドチェックを行う。
ENを有効化する際にResolutionでダイアログを表示後、結果をOnActivityResult
で受けた後、改めてENの有効化を実行する必要がある。
現在iOSで接触確認(Exposure Notification: EN)API v2の動作確認ができていない。
そのためEN v2を無効化(v1に固定)してある。
Lines 66 to 67 in 25453c8
ENv2を使用してDetectExposureを実行した場合、戻値のENExposureDetectionSummary
の内容がすべて0のものが返される。
ExposureDetectionSummary
AttenuationDurations:
DaysSinceLastExposure: 0
MatchedKeyCount: 0
MaximumRiskScore: 0
MaximumRiskScoreFullRange: 0
RiskScoreSumFullRange: 0
Metadata: {
attenuationDurations = (
);
maximumRiskScoreFullRange = 0;
riskScoreSumFullRange = 0;
}
ENv1を使用した場合、同じTEKsで実験しても、問題なく接触確認が機能する。
Androidでは問題なく、ENv2を使った接触確認が機能している。
// https://developer.apple.com/documentation/exposurenotification/enexposureconfiguration
// https://developer.apple.com/documentation/exposurenotification/enexposureconfiguration/exposure_risk_value_calculation_in_exposurenotification_version_1
public class AppleExposureConfiguration
{
// Configuring Duration
#region These properties are available in iOS 12.5, and in iOS 13.5 and later.
public double ImmediateDurationWeight { get; set; } = 100;
public double MediumDurationWeight { get; set; } = 100;
public double NearDurationWeight { get; set; } = 100;
public double OtherDurationWeight { get; set; } = 100;
public int DaysSinceLastExposureThreshold { get; set; } = 0;
// Configuring Infectiousness
// Must Specify v2
public IDictionary<int, Infectiousness> InfectiousnessForDaysSinceOnsetOfSymptoms { get; set; } = new Dictionary<int, Infectiousness>() {
{ -14, Infectiousness.High },
{ -13, Infectiousness.High },
{ -12, Infectiousness.High },
{ -11, Infectiousness.High },
{ -10, Infectiousness.High },
{ -9, Infectiousness.High },
{ -8, Infectiousness.High },
{ -7, Infectiousness.High },
{ -6, Infectiousness.High },
{ -5, Infectiousness.High },
{ -4, Infectiousness.High },
{ -3, Infectiousness.High },
{ -2, Infectiousness.High },
{ -1, Infectiousness.High },
{ 0, Infectiousness.High },
{ 1, Infectiousness.High },
{ 2, Infectiousness.High },
{ 3, Infectiousness.High },
{ 4, Infectiousness.High },
{ 5, Infectiousness.High },
{ 6, Infectiousness.High },
{ 7, Infectiousness.High },
{ 8, Infectiousness.High },
{ 9, Infectiousness.High },
{ 10, Infectiousness.High },
{ 11, Infectiousness.High },
{ 12, Infectiousness.High },
{ 13, Infectiousness.High },
{ 14, Infectiousness.High },
};
public double InfectiousnessHighWeight { get; set; } = 100.0; // The range of this value is 0-250%
public double InfectiousnessStandardWeight { get; set; } = 100.0; // The range of this value is 0-250%
// Configuring Report Types
public double ReportTypeConfirmedClinicalDiagnosisWeight { get; set; } = 100.0;
public double ReportTypeConfirmedTestWeight { get; set; } = 100.0;
public double ReportTypeRecursiveWeight { get; set; } = 100.0;
public double ReportTypeSelfReportedWeight { get; set; } = 100.0;
public ReportType ReportTypeNoneMap { get; set; } = ReportType.Unknown;
public int[] AttenuationLevelValues { get; set; } = { 1, 2, 3, 4, 5, 6, 7, 8 };
public int[] DaysSinceLastExposureLevelValues { get; set; } = { 1, 2, 3, 4, 5, 6, 7, 8 };
public int[] DurationLevelValues { get; set; } = { 1, 2, 3, 4, 5, 6, 7, 8 };
public int[] TransmissionRiskLevelValues { get; set; } = { 1, 2, 3, 4, 5, 6, 7, 8 };
public IDictionary<object, object> Metadata { get; set; } = new Dictionary<object, object>();
public byte MinimumRiskScore { get; set; } = 0;
#endregion
#region These properties are available in iOS 12.5, and in iOS 13.6 and later.
public int[] AttenuationDurationThreshold { get; set; } = { 50, 70 };
public double MinimumRiskScoreFullRange { get; set; } = 0.0;
#endregion
testExport-12-records-1-of-1.zip
{"temporaryExposureKeys":[
{
"key":"tJsz1lw5+DeEOLp3rtnbgg==",
"rollingStartNumber":2696544,
"rollingPeriod":144,
"reportType":1,
"transmissionRisk":8
},
{
"key":"tYwc0Z0vIvW6TS4MGITW+Q==",
"rollingStartNumber":2696688,
"rollingPeriod":144,
"reportType":1,
"transmissionRisk":8
},
{
"key":"/i3MbrjanFvU1PcgqSuvhw==",
"rollingStartNumber":2696832,
"rollingPeriod":144,
"reportType":1,
"transmissionRisk":8
},
{
"key":"GmfZUSUXla2JwOYyEPhTaA==",
"rollingStartNumber":2696976,
"rollingPeriod":144,
"reportType":1,
"transmissionRisk":8
},
{
"key":"vljPVh8MpsJkih7TlgZBsA==",
"rollingStartNumber":2697120,
"rollingPeriod":144,
"reportType":1,
"transmissionRisk":8
},
{
"key":"z10UW6wzahpRn6dAgrmCKQ==",
"rollingStartNumber":2697264,
"rollingPeriod":144,
"reportType":1,
"transmissionRisk":8
},
{
"key":"xiqd/4/Q5CCT0xGQUdsYhg==",
"rollingStartNumber":2697408,
"rollingPeriod":144,
"reportType":1,
"transmissionRisk":8
},
{
"key":"59EgCCvAyyuuPM3LxLYaxQ==",
"rollingStartNumber":2697984,
"rollingPeriod":144,
"reportType":1,
"transmissionRisk":8
},
{
"key":"biCadeEWdABv4Ei6r+H9kw==",
"rollingStartNumber":2698128,
"rollingPeriod":144,
"reportType":1,
"transmissionRisk":8
},
{
"key":"aICg2wk8GZ8EDWIP9VdXuQ==",
"rollingStartNumber":2698272,
"rollingPeriod":144,
"reportType":1,
"transmissionRisk":8
},
{
"key":"WecgOMdDMeusIzVZBlDLSA==",
"rollingStartNumber":2698416,
"rollingPeriod":144,
"reportType":1,
"transmissionRisk":8
},
{
"key":"6UIIIPp7z4K1fZyK9YhZzQ==",
"rollingStartNumber":2698560,
"rollingPeriod":144,
"reportType":1,
"transmissionRisk":8
}
]}
外部からCancellationTokenSourceを受け取ってキャンセル対応できるようにする。
iOSの場合はDetectExposure
周りで渡すことができる。
AndroidのProvideDiagnosisKeys
には同様の処理はないため、ProvideDiagnosisKeysを実行してからBroadcastReceiverが呼ばれるまでの時間経過でタイムアウト・キャンセルができるようにする。
keiji/en-calibration-server#5 に合わせてsymptomOnsetDate
を含める。
あくまでサンプルなのでsymptomOnsetDate
は指定せず「取得できたTEKの数 / 2」日前固定とする。
"daily_summaries": [
{
"DaysSinceEpoch": 18784,
"DaySummary": {
"MaximumScore": 0.0,
"ScoreSum": 0.0,
"WeightedDurationSum": 75360.0
},
以前、Androidのネイティブアプリから取得したときはちゃんと値が来ていたので何らかの異常があると思われる。
https://gist.github.com/keiji/ceab795cb29ba36352a9374cf4e48686
EN APIの接触確認の条件設定(ExposureConfiguration.cs)の各値が試行錯誤をしていたままになっているので、それぞれの設定値の初期値に変更する。
GoogleDiagnosisKeysDataMappingConfig
や AppleExposureV2Configuration. InfectiousnessForDaysSinceOnsetOfSymptoms
のように初期値がnull、かつ必ず設定の必要がある項目については初期値を要検討(nullかデフォルトで値を入れておくか)。
https://github.com/keiji/chino/pull/new/exposuredata_collect_server
ExposureData APIへの対応
現在、クラス、メソッド、プロパティその他のアクセススコープはpublicとprivateが主になっているが、publicのものについてはその必要があるかを検討して、スコープが適切になるように見直す。
DailySummaryにある日付を示す値がiOSではDate
と日付を示すのに対して、AndroidではgetDaysSinceEpoch()
と「Epochからの経過日数」と定義が異なる。
ENExposureDaySummary .date
https://developer.apple.com/documentation/exposurenotification/enexposuredaysummary/3644403-date
これらの違いを吸収する仕組みが現在のchinoに実装されておらず、iOSではDateMillisSinceEpochとして値を取得しているので、接触確認後の日付処理が正しく行われないことになる。
Android版
chino/Chino.Android/DailySummary.cs
Lines 17 to 19 in 698eb4f
"daily_summaries": [
{
"DaysSinceEpoch": 18784,
"DaySummary": {
"MaximumScore": 0.0,
"ScoreSum": 0.0,
"WeightedDurationSum": 75360.0
},
iOS版
chino/Chino.iOS/DailySummary.cs
Lines 17 to 19 in 698eb4f
"daily_summaries": [
{
"DaysSinceEpoch": 1622937600000,
"DaySummary": {
"MaximumScore": 1860.0,
"ScoreSum": 51660.0,
"WeightedDurationSum": 51660.0
},
cocoa-mhlw/cocoa#334 (comment) に関連。
days_since_onset_of_symptoms
について対応する上で、当初 keiji/en-calibration-server#2 で、症状が出ていないなどの理由で症状発生日が確定できないときに、daysSinceOnsetOfSymptoms
のキーを値DAYS_SINCE_ONSET_OF_SYMPTOMS_UNKNOWN
(2147483647
)として扱うようにしていた。
(iOSで規定されているENDaysSinceOnsetOfSymptomsUnknown
はlong値の最大値であるため、int型のAndroidでは設定できない。そのため、Android側の値に合わせる形とした経緯がある)
この方法はiOSであれば問題なかったがInfectiousnessWhenDaysSinceOnsetMissing
の取り扱いとなった。一方、Androidでは接触確認の結果が返されない事象が発生した。
days_since_onset_of_symptoms
の値に想定されている(-14
から14
)までの範囲を設定して再テストしたところ、問題なく接触確認処理が行われ、結果を受け取ることができた。
このことから、Android版においてdays_since_onset_of_symptoms
に設定する値は-14
から14
の範囲でなければならないと言う制約があるものと推測する。
AndroidとiOSの仕様差を吸収するため、daysSinceOnsetOfSymptoms
必ずサーバーに送るようにする。サンプルアプリでは症状発生日の入力項目を設けていないので、取得できたTEKに適切な数値を設定して対応とする。
現在はServiceStateUpdatedのBroadcastをハンドリングしていない。
これは各アプリでもBroadcastReceiverを持つことでハンドリングできるが、統合性を考えるとCappuccinoでハンドリングする方がよいか検討する(iOSで同種の処理は存在する?)。
ExposureNotificationClientをインスタンス化するタイミングでENManagerもインスタンス化しているが、接触確認APIを使える状態にない(Entitlements.plistがない。権限がない)は強制終了する。
Mockに置き換え出来るようにするために、ENManagerのインスタンス化は遅延する必要がある。
現在は定数ファイルConstants.cs
でビルド時に決定しているが、これをJSONのファイルとして保存して、再ビルドなしにカスタマイズできるようにしたい。
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.