Windows Recall 會評估透過 UserActivity.ContentInfo JSON 提供的元資料,以決定是否擷取視窗,以及如何依企業資料遺失防護(DLP)政策分類快照。 透過提供敏感性標籤(在已知時), Recall 可以查詢 DLP 提供者執行決策(例如區塊擷取),並向使用者顯示適當的元資料。
何時傳送元資料
當發生以下情況時發送或更新UserActivity:
- 有效文件或項目變更
- 敏感度標籤會被新增、移除或更改
- 狀態從不確定轉變到已知
- 你的應用程式啟動(建立基準點)
敏感度模型
您的應用程式可在以下三種狀態之一回報內容:
-
敏感:將
informationProtection物件包含在labels陣列中 -
非敏感:完全省略該
informationProtection物件 -
未確定:包含
informationProtection.state = "undetermined"(Recall 阻止捕獲直到狀態解決)
物件的缺席 informationProtection 表示內容並非敏感。
JSON 結構
推薦的頂層領域:
-
@context:https://schema.org -
@type例如,「DocumentObject」、「Event」、「Article」 -
identifier:穩定的唯一ID
資訊保護對象(僅供敏感或不確定的使用)範本(示範性,非字面 JSON):
"informationProtection": {
"@type": "SensitivityLabel",
"state": "<state>", // "sensitive" or "undetermined"
"labels": [ // include only when state == "sensitive"
{
"labelID": "<label GUID>",
"organizationID": "<tenant GUID>"
}
]
}
槼:
- 替換
<state>為sensitive或undetermined。 - 僅在狀態為
labels時包含sensitive陣列。 -
@type內部物件總是SensitivityLabel。 - 允許使用多個標籤; Recall 套用由 DLP 提供者回傳的最嚴格標準。
簡略範例
敏感(單曲):
{
"@context": "https://schema.org",
"@type": "DocumentObject",
"identifier": "doc-123",
"informationProtection": {
"@type": "SensitivityLabel",
"state": "sensitive",
"labels": [
{
"labelID": "F96E0B19-8C3A-4D5A-8B9A-2E8CFC43247B",
"organizationID": "D3FE4C20-9C77-45AB-A8E7-9870D3C9C856"
}
]
}
}
非敏感
{
"@context": "https://schema.org",
"@type": "DocumentObject",
"identifier": "doc-123"
}
未定
{
"@context": "https://schema.org",
"@type": "DocumentObject",
"identifier": "doc-123",
"informationProtection": {
"@type": "SensitivityLabel",
"state": "undetermined"
}
}
多重標籤範例
"informationProtection": {
"@type": "SensitivityLabel",
"state": "sensitive",
"labels": [
{
"labelID": "F96E0B19-8C3A-4D5A-8B9A-2E8CFC43247B",
"organizationID": "D3FE4C20-9C77-45AB-A8E7-9870D3C9C856"
},
{
"labelID": "9A724CF8-E7D2-4B1C-8F4A-1D2E7B3A6C8D",
"organizationID": "7C56AB24-9E32-44FA-B7D8-1E9F43C7A92B"
}
]
}
API 使用(C#)
輔助法
以下輔助方法示範如何使用敏感度標籤更新 ContentInfo。
private async Task UpdateContentInfoAsync(
string contentId,
string state, // "sensitive" | "undetermined" | "none"
IEnumerable<(string LabelId, string OrgId)>? labels = null)
{
var channel = UserActivityChannel.GetDefault();
var activity = await channel.GetOrCreateUserActivityAsync(contentId);
activity.ActivationUri = new Uri($"my-app://content/{contentId}");
string json;
if (state == "sensitive" && labels != null)
{
var labelItems = string.Join(",",
labels.Select(l => $@"{{ \"labelID\": \"{l.LabelId}\", \"organizationID\": \"{l.OrgId}\" }}"));
json = $@"{{
\"@context\": \"https://schema.org\",
\"@type\": \"DocumentObject\",
\"identifier\": \"{contentId}\",
\"informationProtection\": {{
\"@type\": \"SensitivityLabel\",
\"state\": \"sensitive\",
\"labels\": [ {labelItems} ]
}}
}}";
}
else if (state == "undetermined")
{
json = $@"{{
\"@context\": \"https://schema.org\",
\"@type\": \"DocumentObject\",
\"identifier\": \"{contentId}\",
\"informationProtection\": {{
\"@type\": \"SensitivityLabel\",
\"state\": \"undetermined\"
}}
}}";
}
else
{
json = $@"{{
\"@context\": \"https://schema.org\",
\"@type\": \"DocumentObject\",
\"identifier\": \"{contentId}\"
}}";
}
activity.ContentInfo = UserActivityContentInfo.FromJson(json);
await activity.SaveAsync();
}
拉動處理程序
以下拉取處理程式示範如何回應按需 UserActivity 請求:
private async void UserActivityRequested(
UserActivityRequestManager sender,
UserActivityRequestedEventArgs args)
{
var deferral = args.GetDeferral();
try
{
string id = GetCurrentContentId();
var (state, labels) = GetCurrentSensitivity(); // app logic
var channel = UserActivityChannel.GetDefault();
var activity = await channel.GetOrCreateUserActivityAsync(id);
activity.ActivationUri = new Uri($"my-app://content/{id}");
string json = BuildContentInfoJson(id, state, labels);
activity.ContentInfo = UserActivityContentInfo.FromJson(json);
args.Request.SetUserActivity(activity);
}
finally
{
deferral.Complete();
}
}
推與拉
採用混合方式:
- 初始拉動建立基準
- 變更時立即推送更新
優點:低延遲、避免過時標籤、降低輪詢開銷、支援快速按需擷取。