diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2024-02-02 16:44:22 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2024-02-02 16:44:22 +0000 |
commit | 09159e4aa8304fbee20969bebafb4084f77a22e4 (patch) | |
tree | 1baaf11d29bbd719debe25d639cbc0c16336db3e | |
parent | 660f781f6e03874a5f22014ada703ac3a77834d9 (diff) | |
parent | acc6941aebdff5ac139e01aa60f24fb68656c39e (diff) | |
download | Permission-09159e4aa8304fbee20969bebafb4084f77a22e4.tar.gz |
Snap for 11397440 from acc6941aebdff5ac139e01aa60f24fb68656c39e to mainline-healthfitness-releaseaml_hef_341613000
Change-Id: I8b16fe2a5b4523fa26afebba6f78baa4592fea82
18 files changed, 346 insertions, 105 deletions
diff --git a/PermissionController/res/values-da/strings.xml b/PermissionController/res/values-da/strings.xml index a01f54f55..db2b515b5 100644 --- a/PermissionController/res/values-da/strings.xml +++ b/PermissionController/res/values-da/strings.xml @@ -352,10 +352,10 @@ <string name="role_assistant_label" msgid="4727586018198208128">"Standardapp for digital assistent"</string> <string name="role_assistant_short_label" msgid="3369003713187703399">"App for digital assistent"</string> <string name="role_assistant_description" msgid="6622458130459922952">"Assistanceapps kan hjælpe dig på baggrund af oplysningerne på den aktuelle skærm. Nogle apps understøtter både startertjenester og tjenester til indtaling for at give dig integreret assistance."</string> - <string name="role_browser_label" msgid="2877796144554070207">"Standardbrowserapp"</string> + <string name="role_browser_label" msgid="2877796144554070207">"Standardapp til browsing"</string> <string name="role_browser_short_label" msgid="6745009127123292296">"Browserapp"</string> <string name="role_browser_description" msgid="3465253637499842671">"Apps, der giver dig adgang til internettet og viser links, som du trykker på"</string> - <string name="role_browser_request_title" msgid="2895200507835937192">"Vil du angive <xliff:g id="APP_NAME">%1$s</xliff:g> som din standardbrowserapp?"</string> + <string name="role_browser_request_title" msgid="2895200507835937192">"Vil du angive <xliff:g id="APP_NAME">%1$s</xliff:g> som din standardapp til browsing?"</string> <string name="role_browser_request_description" msgid="5888803407905985941">"Der kræves ingen tilladelser"</string> <string name="role_dialer_label" msgid="1100224146343237968">"Standardapp til opkald"</string> <string name="role_dialer_short_label" msgid="7186888549465352489">"Opkaldsapp"</string> diff --git a/PermissionController/res/values-ja/strings.xml b/PermissionController/res/values-ja/strings.xml index 7784829a1..9042b44d0 100644 --- a/PermissionController/res/values-ja/strings.xml +++ b/PermissionController/res/values-ja/strings.xml @@ -56,8 +56,8 @@ <string name="grant_dialog_button_keey_approximate_location" msgid="438025182769080011">"おおよその位置情報を保持"</string> <string name="grant_dialog_button_allow_one_time" msgid="2618088516449706391">"今回のみ"</string> <string name="grant_dialog_button_allow_background" msgid="8236044729434367833">"常に許可"</string> - <string name="grant_dialog_button_allow_all_files" msgid="4955436994954829894">"すべてのファイルの管理を許可"</string> - <string name="grant_dialog_button_allow_media_only" msgid="4832877658422573832">"メディア ファイルへのアクセスを許可"</string> + <string name="grant_dialog_button_allow_all_files" msgid="4955436994954829894">"すべての管理を許可"</string> + <string name="grant_dialog_button_allow_media_only" msgid="4832877658422573832">"アクセスのみ許可"</string> <string name="app_permissions_breadcrumb" msgid="5136969550489411650">"アプリ"</string> <string name="app_permissions" msgid="3369917736607944781">"アプリの権限"</string> <string name="unused_apps" msgid="2058057455175955094">"使用されていないアプリ"</string> @@ -86,7 +86,7 @@ <string name="app_permissions_group_summary" msgid="8788419008958284002">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="COUNT_1">%2$d</xliff:g> 個のアプリを許可"</string> <string name="app_permissions_group_summary2" msgid="4329922444840521150">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="COUNT_1">%2$d</xliff:g> 件のアプリを許可"</string> <string name="menu_show_system" msgid="4254021607027872504">"システムアプリを表示"</string> - <string name="menu_hide_system" msgid="3855390843744028465">"システムアプリを表示しない"</string> + <string name="menu_hide_system" msgid="3855390843744028465">"システムアプリを非表示"</string> <string name="menu_show_7_days_data" msgid="8979611198508523706">"過去 7 日間を表示"</string> <string name="menu_show_24_hours_data" msgid="8228054833323380780">"過去 24 時間を表示"</string> <string name="manage_permission" msgid="2895385393037061964">"権限の管理"</string> @@ -351,7 +351,7 @@ <string name="accessibility_service_dialog_bottom_text_multiple" msgid="7009848932395519852">"これらのアプリでは、画面、アクション、入力の表示、アクションの実行、ディスプレイの操作を行えます。"</string> <string name="role_assistant_label" msgid="4727586018198208128">"デフォルトのデジタル アシスタント アプリ"</string> <string name="role_assistant_short_label" msgid="3369003713187703399">"デジタル アシスタント アプリ"</string> - <string name="role_assistant_description" msgid="6622458130459922952">"アシストアプリは、表示している画面の情報に基づいてアシスタントを提供します。一部のアプリはランチャーと音声入力サービスの両方に対応しており、統合されたアシスタントを提供します。"</string> + <string name="role_assistant_description" msgid="6622458130459922952">"アシストアプリは、表示している画面の情報に基づいてサポートを提供します。一部のアプリはランチャーと音声入力サービスの両方に対応しており、統合されたサポートを提供します。"</string> <string name="role_browser_label" msgid="2877796144554070207">"デフォルトのブラウザアプリ"</string> <string name="role_browser_short_label" msgid="6745009127123292296">"ブラウザアプリ"</string> <string name="role_browser_description" msgid="3465253637499842671">"インターネットにアクセスするためのアプリです。タップしたリンクは、このアプリで開きます。"</string> diff --git a/PermissionController/res/values-ko/strings.xml b/PermissionController/res/values-ko/strings.xml index 9ab5a5736..143fce74a 100644 --- a/PermissionController/res/values-ko/strings.xml +++ b/PermissionController/res/values-ko/strings.xml @@ -351,7 +351,7 @@ <string name="accessibility_service_dialog_bottom_text_multiple" msgid="7009848932395519852">"이 앱이 내 화면, 작업, 입력 내용을 보고 작업을 실행하며 디스플레이를 제어할 수 있습니다."</string> <string name="role_assistant_label" msgid="4727586018198208128">"기본 디지털 어시스턴트 앱"</string> <string name="role_assistant_short_label" msgid="3369003713187703399">"디지털 어시스턴트 앱"</string> - <string name="role_assistant_description" msgid="6622458130459922952">"지원 앱은 화면에 표시된 정보에 맞게 도움을 줄 수 있습니다. 일부 앱은 통합된 지원을 제공하기 위해 런처와 음성 입력 서비스를 모두 지원합니다."</string> + <string name="role_assistant_description" msgid="6622458130459922952">"지원 앱은 화면에 표시된 정보를 기반으로 도움을 줄 수 있습니다. 일부 앱은 통합된 지원을 제공하기 위해 런처와 음성 입력 서비스를 모두 지원합니다."</string> <string name="role_browser_label" msgid="2877796144554070207">"기본 브라우저 앱"</string> <string name="role_browser_short_label" msgid="6745009127123292296">"브라우저 앱"</string> <string name="role_browser_description" msgid="3465253637499842671">"인터넷에 액세스하고 탭하는 링크를 표시하는 앱"</string> diff --git a/PermissionController/res/values-pa-v33/strings.xml b/PermissionController/res/values-pa-v33/strings.xml index 8f1b9a285..0aa143302 100644 --- a/PermissionController/res/values-pa-v33/strings.xml +++ b/PermissionController/res/values-pa-v33/strings.xml @@ -28,7 +28,7 @@ <string name="safety_center_entry_group_item_content_description" msgid="7348298582877249787">"ਸੂਚੀ ਆਈਟਮ। <xliff:g id="ENTRY_ITEM_TITLE">%1$s</xliff:g>. <xliff:g id="ENTRY_ITEM_SUMMARY">%2$s</xliff:g>"</string> <string name="safety_center_entry_content_description" msgid="3639565652938224321">"<xliff:g id="ENTRY_ITEM_TITLE">%1$s</xliff:g>. <xliff:g id="ENTRY_ITEM_SUMMARY">%2$s</xliff:g>"</string> <string name="safety_center_more_issues_card_title" msgid="7425844746197493312">"ਹੋਰ ਅਲਰਟ"</string> - <string name="safety_center_dismissed_issues_card_title" msgid="2340129842725145733">"ਖਾਰਜ ਕੀਤੀਆਂ ਗਈਆਂ ਸੁਚੇਤਨਾਵਾਂ"</string> + <string name="safety_center_dismissed_issues_card_title" msgid="2340129842725145733">"ਖਾਰਜ ਕੀਤੇ ਅਲਰਟ"</string> <string name="safety_center_more_issues_card_expand_action" msgid="7109451851052272946">"{count,plural, =1{ਵਿਸਤਾਰ ਕਰੋ ਅਤੇ ਇੱਕ ਹੋਰ ਅਲਰਟ ਦੇਖੋ}one{ਵਿਸਤਾਰ ਕਰੋ ਅਤੇ # ਹੋਰ ਅਲਰਟ ਦੇਖੋ}other{ਵਿਸਤਾਰ ਕਰੋ ਅਤੇ # ਹੋਰ ਅਲਰਟ ਦੇਖੋ}}"</string> <string name="safety_center_issue_card_prefix_content_description" msgid="1447445289637043544">"ਅਲਰਟ। <xliff:g id="ISSUE_CARD_TITLE">%1$s</xliff:g>"</string> <string name="safety_center_resolved_issue_fallback" msgid="8548932070610766651">"ਕਾਰਵਾਈ ਪੂਰੀ ਹੋਈ"</string> diff --git a/PermissionController/res/values-pa/strings.xml b/PermissionController/res/values-pa/strings.xml index 1c4539642..613f77c6e 100644 --- a/PermissionController/res/values-pa/strings.xml +++ b/PermissionController/res/values-pa/strings.xml @@ -371,7 +371,7 @@ <string name="role_sms_search_keywords" msgid="8022048144395047352">"ਲਿਖਤ ਸੁਨੇਹਾ, ਲਿਖਤ ਭੇਜਣਾ, ਸੁਨੇਹੇ, ਸੁਨੇਹਾ ਭੇਜਣਾ"</string> <string name="role_emergency_label" msgid="7028825857206842366">"ਪੂਰਵ-ਨਿਰਧਾਰਤ ਸੰਕਟਕਾਲੀਨ ਐਪ"</string> <string name="role_emergency_short_label" msgid="2388431453335350348">"ਸੰਕਟਕਾਲੀਨ ਐਪ"</string> - <string name="role_emergency_description" msgid="5051840234887686630">"ਐਪਾਂ ਜੋ ਤੁਹਾਨੂੰ ਤੁਹਾਡੀ ਡਾਕਟਰੀ ਜਾਣਕਾਰੀ ਰਿਕਾਰਡ ਕਰਨ ਅਤੇ ਇਸਨੂੰ ਸੰਕਟਕਾਲੀਨ ਮਦਦਗਾਰਾਂ ਤੱਕ ਪਹੁੰਚਯੋਗ ਬਣਾਉਣ ਦਿੰਦੀਆਂ ਹਨ; ਗੰਭੀਰ ਮੌਸਮੀ ਘਟਨਾਵਾਂ ਅਤੇ ਆਫ਼ਤਾਂ ਬਾਰੇ ਸੁਚੇਤਨਾਵਾਂ ਪ੍ਰਾਪਤ ਕਰਨ ਦਿੰਦੀਆਂ ਹਨ; ਤੁਹਾਨੂੰ ਮਦਦ ਦੀ ਲੋੜ ਪੈਣ \'ਤੇ ਹੋਰਾਂ ਨੂੰ ਸੂਚਿਤ ਕਰਨ ਦਿੰਦੀਆਂ ਹਨ"</string> + <string name="role_emergency_description" msgid="5051840234887686630">"ਐਪਾਂ ਜੋ ਤੁਹਾਨੂੰ ਤੁਹਾਡੀ ਡਾਕਟਰੀ ਜਾਣਕਾਰੀ ਰਿਕਾਰਡ ਕਰਨ ਅਤੇ ਇਸਨੂੰ ਐਮਰਜੈਂਸੀ ਮਦਦਗਾਰਾਂ ਤੱਕ ਪਹੁੰਚਯੋਗ ਬਣਾਉਣ ਦਿੰਦੀਆਂ ਹਨ; ਬਹੁਤ ਜ਼ਿਆਦਾ ਖਰਾਬ ਮੌਸਮੀ ਘਟਨਾਵਾਂ ਅਤੇ ਆਫ਼ਤਾਂ ਬਾਰੇ ਅਲਰਟ ਪ੍ਰਾਪਤ ਕਰਨ ਦਿੰਦੀਆਂ ਹਨ; ਤੁਹਾਨੂੰ ਮਦਦ ਦੀ ਲੋੜ ਪੈਣ \'ਤੇ ਹੋਰਾਂ ਨੂੰ ਸੂਚਿਤ ਕਰਨ ਦਿੰਦੀਆਂ ਹਨ"</string> <string name="role_emergency_request_title" msgid="8469579020654348567">"ਕੀ <xliff:g id="APP_NAME">%1$s</xliff:g> ਨੂੰ ਤੁਹਾਡੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਸੰਕਟਕਾਲੀਨ ਐਪ ਵਜੋਂ ਸੈੱਟ ਕਰਨਾ ਹੈ?"</string> <string name="role_emergency_request_description" msgid="131645948770262850">"ਕਿਸੇ ਇਜਾਜ਼ਤ ਦੀ ਲੋੜ ਨਹੀਂ ਹੈ"</string> <string name="role_emergency_search_keywords" msgid="1920007722599213358">"ice"</string> diff --git a/PermissionController/res/values-zu/strings.xml b/PermissionController/res/values-zu/strings.xml index b4f177a15..c90048a4e 100644 --- a/PermissionController/res/values-zu/strings.xml +++ b/PermissionController/res/values-zu/strings.xml @@ -198,7 +198,7 @@ <string name="app_permission_location_accuracy" msgid="7166912915040018669">"Sebenzisa indawo eqondile"</string> <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Uma indawo ngqo ivaliwe, ama-app angakwazi ukufinyelela indawo yakho elinganiselwayo"</string> <string name="app_permission_title" msgid="2090897901051370711">"<xliff:g id="PERM">%1$s</xliff:g> imvume"</string> - <string name="app_permission_header" msgid="2951363137032603806">"<xliff:g id="PERM">%1$s</xliff:g> ukufinyelela kwale app"</string> + <string name="app_permission_header" msgid="2951363137032603806">"ukufinyelela kwale app ku<xliff:g id="PERM">%1$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Bona zonke izimvume ze-<xliff:g id="APP">%1$s</xliff:g>"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Bona zonke izinhlelo zokusebenza ngale mvume"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Bonisa ukusetshenziswa kwe-microphone kamsizi"</string> diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/GrantPermissionsActivity.java b/PermissionController/src/com/android/permissioncontroller/permission/ui/GrantPermissionsActivity.java index a6e521138..53f8fe712 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/GrantPermissionsActivity.java +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/GrantPermissionsActivity.java @@ -66,7 +66,6 @@ import androidx.annotation.GuardedBy; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.StringRes; -import androidx.core.util.Consumer; import androidx.core.util.Preconditions; import com.android.modules.utils.build.SdkLevel; @@ -417,7 +416,7 @@ public class GrantPermissionsActivity extends SettingsActivity mViewModel.sendDirectlyToSettings(top, info.getGroupName()); return; } else if (info.getOpenPhotoPicker()) { - mViewModel.openPhotoPicker(top, GRANTED_USER_SELECTED); + mViewModel.openPhotoPicker(top); return; } @@ -604,16 +603,14 @@ public class GrantPermissionsActivity extends SettingsActivity @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); - Consumer<Intent> callback = mViewModel.getActivityResultCallback(); - if (callback == null || (requestCode != APP_PERMISSION_REQUEST_CODE - && requestCode != PHOTO_PICKER_REQUEST_CODE)) { + if (requestCode != APP_PERMISSION_REQUEST_CODE + && requestCode != PHOTO_PICKER_REQUEST_CODE) { return; } if (requestCode == PHOTO_PICKER_REQUEST_CODE) { data = new Intent("").putExtra(INTENT_PHOTOS_SELECTED, resultCode == RESULT_OK); } - callback.accept(data); - mViewModel.setActivityResultCallback(null); + mViewModel.handleCallback(data, requestCode); } @Override @@ -633,11 +630,10 @@ public class GrantPermissionsActivity extends SettingsActivity mPreMergeShownGroupName = null; } - if (Objects.equals(READ_MEDIA_VISUAL, name) - && result == GrantPermissionsViewHandler.GRANTED_USER_SELECTED) { + if (Objects.equals(READ_MEDIA_VISUAL, name) && result == GRANTED_USER_SELECTED) { // Only the top activity can receive activity results Activity top = mFollowerActivities.isEmpty() ? this : mFollowerActivities.get(0); - mViewModel.openPhotoPicker(top, result); + mViewModel.openPhotoPicker(top); logGrantPermissionActivityButtons(name, affectedForegroundPermissions, result); return; } diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/PermissionAppsFragment.java b/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/PermissionAppsFragment.java index 6bcf926d3..ba839ee0e 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/PermissionAppsFragment.java +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/PermissionAppsFragment.java @@ -35,6 +35,7 @@ import android.os.Handler; import android.os.Looper; import android.os.UserHandle; import android.provider.Settings; +import android.safetycenter.SafetyCenterManager; import android.util.ArrayMap; import android.view.Menu; import android.view.MenuInflater; @@ -93,6 +94,8 @@ public final class PermissionAppsFragment extends SettingsWithLargeHeader implem private static final int MENU_PERMISSION_USAGE = MENU_HIDE_SYSTEM + 1; + private static final String PRIVACY_CONTROLS_ACTION = "android.settings.PRIVACY_CONTROLS"; + /** * Create a bundle with the arguments needed by this fragment * @@ -281,12 +284,30 @@ public final class PermissionAppsFragment extends SettingsWithLargeHeader implem findPreference(ALLOWED_FOREGROUND.getCategoryName()).setVisible(false); } + @RequiresApi(Build.VERSION_CODES.TIRAMISU) + private String getPrivacyControlsIntent() { + SafetyCenterManager safetyCenterManager = + getContext().getSystemService(SafetyCenterManager.class); + if (safetyCenterManager.isSafetyCenterEnabled()) { + return PRIVACY_CONTROLS_ACTION; + } else { + return Settings.ACTION_PRIVACY_SETTINGS; + } + } + @RequiresApi(Build.VERSION_CODES.S) private CardViewPreference createSensorCard() { boolean isLocation = Manifest.permission_group.LOCATION.equals(mPermGroupName); Context context = getPreferenceManager().getContext(); - String action = isLocation ? Settings.ACTION_LOCATION_SOURCE_SETTINGS - : Settings.ACTION_PRIVACY_SETTINGS; + + String action; + if (isLocation) { + action = Settings.ACTION_LOCATION_SOURCE_SETTINGS; + } else if (SdkLevel.isAtLeastT()) { + action = getPrivacyControlsIntent(); + } else { + action = Settings.ACTION_PRIVACY_SETTINGS; + } CardViewPreference sensorCard = new CardViewPreference(context, action); sensorCard.setKey(BLOCKED_SENSOR_PREF_KEY); sensorCard.setIcon(Utils.getBlockedIcon(mPermGroupName)); diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/model/GrantPermissionsViewModel.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/model/GrantPermissionsViewModel.kt index 3f19db475..d9fd7f2ea 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/model/GrantPermissionsViewModel.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/model/GrantPermissionsViewModel.kt @@ -186,6 +186,18 @@ class GrantPermissionsViewModel( private var appPermGroupLiveDatas = mutableMapOf<String, LightAppPermGroupLiveData>() + internal data class ResultCallback(val consumer: Consumer<Intent>, val requestCode: Int) + + private var activityResultCallback: ResultCallback? = null + + init { + if (storedState?.containsKey(SAVED_REQUEST_CODE_KEY) == true) { + if (storedState.getInt(SAVED_REQUEST_CODE_KEY) == PHOTO_PICKER_REQUEST_CODE) { + setPhotoPickerCallback() + } + } + } + /** * A class which represents a correctly requested permission group, and the buttons and messages * which should be shown with it. @@ -202,8 +214,6 @@ class GrantPermissionsViewModel( val groupName = groupInfo.name } - var activityResultCallback: Consumer<Intent>? = null - /** A LiveData which holds a list of the currently pending RequestInfos */ val requestInfosLiveData = object : SmartUpdateMediatorLiveData<List<RequestInfo>>() { @@ -1494,7 +1504,9 @@ class GrantPermissionsViewModel( Log.v( LOG_TAG, "Permission grant result requestId=$sessionId " + - "callingUid=${packageInfo.uid} callingPackage=$packageName permission=$permission " + + "callingUid=${packageInfo.uid} " + + "callingPackage=$packageName " + + "permission=$permission " + "isImplicit=$isImplicit result=$result " + "isPermissionRationaleShown=$isPermissionRationaleShown" ) @@ -1522,6 +1534,7 @@ class GrantPermissionsViewModel( val (groupName, isBackground) = groupKey outState.putInt(getInstanceStateKey(groupName, isBackground), groupState.state) } + activityResultCallback?.let { outState.putInt(SAVED_REQUEST_CODE_KEY, it.requestCode) } } /** @@ -1547,12 +1560,25 @@ class GrantPermissionsViewModel( } } + fun handleCallback(data: Intent?, requestCode: Int) { + val currCallback = activityResultCallback + if (currCallback == null || requestCode != currCallback.requestCode) { + return + } + currCallback.consumer.accept(data) + activityResultCallback = null + } + fun handleHealthConnectPermissions(activity: Activity) { if (activityResultCallback == null) { - activityResultCallback = Consumer { - permGroupsToSkip.add(HEALTH_PERMISSION_GROUP) - requestInfosLiveData.update() - } + activityResultCallback = + ResultCallback( + { + permGroupsToSkip.add(HEALTH_PERMISSION_GROUP) + requestInfosLiveData.update() + }, + APP_PERMISSION_REQUEST_CODE + ) val healthPermissions = unfilteredAffectedPermissions .filter { permission -> isHealthPermission(activity, permission) } @@ -1575,55 +1601,72 @@ class GrantPermissionsViewModel( */ fun sendDirectlyToSettings(activity: Activity, groupName: String) { if (activityResultCallback == null) { - activityResultCallback = Consumer { data -> - if (data?.getStringExtra(EXTRA_RESULT_PERMISSION_INTERACTED) == null) { - // User didn't interact, count against rate limit - val group = - groupStates[groupName to false]?.group - ?: groupStates[groupName to true]?.group ?: return@Consumer - if (group.background.isUserSet) { - KotlinUtils.setGroupFlags( - app, - group, - FLAG_PERMISSION_USER_FIXED to true, - filterPermissions = group.backgroundPermNames - ) - } else { - KotlinUtils.setGroupFlags( - app, - group, - FLAG_PERMISSION_USER_SET to true, - filterPermissions = group.backgroundPermNames - ) - } - } + activityResultCallback = + ResultCallback( + Consumer { data -> + if (data?.getStringExtra(EXTRA_RESULT_PERMISSION_INTERACTED) == null) { + // User didn't interact, count against rate limit + val group = + groupStates[groupName to false]?.group + ?: groupStates[groupName to true]?.group + ?: return@Consumer + if (group.background.isUserSet) { + KotlinUtils.setGroupFlags( + app, + group, + FLAG_PERMISSION_USER_FIXED to true, + filterPermissions = group.backgroundPermNames + ) + } else { + KotlinUtils.setGroupFlags( + app, + group, + FLAG_PERMISSION_USER_SET to true, + filterPermissions = group.backgroundPermNames + ) + } + } - permGroupsToSkip.add(groupName) - // Update our liveData now that there is a new skipped group - requestInfosLiveData.update() - } + permGroupsToSkip.add(groupName) + // Update our liveData now that there is a new skipped group + requestInfosLiveData.update() + }, + APP_PERMISSION_REQUEST_CODE + ) startAppPermissionFragment(activity, groupName) } } - fun openPhotoPicker(activity: Activity, result: Int) { + fun openPhotoPicker(activity: Activity) { if (activityResultCallback != null) { return } if (groupStates[READ_MEDIA_VISUAL to false]?.affectedPermissions == null) { return } - activityResultCallback = Consumer { data -> - val anySelected = data?.getBooleanExtra(INTENT_PHOTOS_SELECTED, true) == true - if (anySelected) { - onPermissionGrantResult(READ_MEDIA_VISUAL, null, result) - } else { - onPermissionGrantResult(READ_MEDIA_VISUAL, null, CANCELED) - } - requestInfosLiveData.update() - } - openPhotoPickerForApp(activity, packageInfo.uid, unfilteredAffectedPermissions, - PHOTO_PICKER_REQUEST_CODE) + setPhotoPickerCallback() + openPhotoPickerForApp( + activity, + packageInfo.uid, + unfilteredAffectedPermissions, + PHOTO_PICKER_REQUEST_CODE + ) + } + + private fun setPhotoPickerCallback() { + activityResultCallback = + ResultCallback( + { data -> + val anySelected = data?.getBooleanExtra(INTENT_PHOTOS_SELECTED, true) == true + if (anySelected) { + onPermissionGrantResult(READ_MEDIA_VISUAL, null, GRANTED_USER_SELECTED) + } else { + onPermissionGrantResult(READ_MEDIA_VISUAL, null, CANCELED) + } + requestInfosLiveData.update() + }, + PHOTO_PICKER_REQUEST_CODE + ) } /** @@ -1634,15 +1677,19 @@ class GrantPermissionsViewModel( */ fun sendToSettingsFromLink(activity: Activity, groupName: String) { startAppPermissionFragment(activity, groupName) - activityResultCallback = Consumer { data -> - val returnGroupName = data?.getStringExtra(EXTRA_RESULT_PERMISSION_INTERACTED) - if (returnGroupName != null) { - permGroupsToSkip.add(returnGroupName) - val result = data.getIntExtra(EXTRA_RESULT_PERMISSION_RESULT, -1) - logSettingsInteraction(returnGroupName, result) - requestInfosLiveData.update() - } - } + activityResultCallback = + ResultCallback( + { data -> + val returnGroupName = data?.getStringExtra(EXTRA_RESULT_PERMISSION_INTERACTED) + if (returnGroupName != null) { + permGroupsToSkip.add(returnGroupName) + val result = data.getIntExtra(EXTRA_RESULT_PERMISSION_RESULT, -1) + logSettingsInteraction(returnGroupName, result) + requestInfosLiveData.update() + } + }, + APP_PERMISSION_REQUEST_CODE + ) } /** @@ -1662,15 +1709,19 @@ class GrantPermissionsViewModel( putExtra(Intent.EXTRA_PERMISSION_GROUP_NAME, groupName) putExtra(Constants.EXTRA_SESSION_ID, sessionId) } - activityResultCallback = Consumer { data -> - val returnGroupName = data?.getStringExtra(EXTRA_RESULT_PERMISSION_INTERACTED) - if (returnGroupName != null) { - permGroupsToSkip.add(returnGroupName) - val result = data.getIntExtra(EXTRA_RESULT_PERMISSION_RESULT, CANCELED) - logSettingsInteraction(returnGroupName, result) - requestInfosLiveData.update() - } - } + activityResultCallback = + ResultCallback( + { data -> + val returnGroupName = data?.getStringExtra(EXTRA_RESULT_PERMISSION_INTERACTED) + if (returnGroupName != null) { + permGroupsToSkip.add(returnGroupName) + val result = data.getIntExtra(EXTRA_RESULT_PERMISSION_RESULT, CANCELED) + logSettingsInteraction(returnGroupName, result) + requestInfosLiveData.update() + } + }, + APP_PERMISSION_REQUEST_CODE + ) activity.startActivityForResult(intent, APP_PERMISSION_REQUEST_CODE) } @@ -1836,6 +1887,7 @@ class GrantPermissionsViewModel( companion object { const val APP_PERMISSION_REQUEST_CODE = 1 const val PHOTO_PICKER_REQUEST_CODE = 2 + const val SAVED_REQUEST_CODE_KEY = "saved_request_code" private const val STATE_UNKNOWN = 0 private const val STATE_ALLOWED = 1 private const val STATE_DENIED = 2 diff --git a/PermissionController/src/com/android/permissioncontroller/permission/utils/KotlinUtils.kt b/PermissionController/src/com/android/permissioncontroller/permission/utils/KotlinUtils.kt index f2aa0ae66..59906283a 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/utils/KotlinUtils.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/utils/KotlinUtils.kt @@ -144,9 +144,6 @@ object KotlinUtils { /** Whether to show the location indicators. */ private const val PROPERTY_LOCATION_INDICATORS_ENABLED = "location_indicators_enabled" - /** Whether location accuracy feature is enabled */ - private const val PROPERTY_LOCATION_ACCURACY_ENABLED = "location_accuracy_enabled" - /** Whether to show 7-day toggle in privacy hub. */ private const val PRIVACY_DASHBOARD_7_DAY_TOGGLE = "privacy_dashboard_7_day_toggle" @@ -252,12 +249,7 @@ object KotlinUtils { /** Whether the location accuracy feature is enabled */ @ChecksSdkIntAtLeast(Build.VERSION_CODES.S) fun isLocationAccuracyEnabled(): Boolean { - return SdkLevel.isAtLeastS() && - DeviceConfig.getBoolean( - DeviceConfig.NAMESPACE_PRIVACY, - PROPERTY_LOCATION_ACCURACY_ENABLED, - true - ) + return SdkLevel.isAtLeastS() } /** Default state of location precision true: default is FINE. false: default is COARSE. */ diff --git a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterFragment.kt b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterFragment.kt index 6f146e48c..9feecf5d4 100644 --- a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterFragment.kt +++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterFragment.kt @@ -92,7 +92,7 @@ abstract class SafetyCenterFragment : PreferenceFragmentCompat() { } val safetyCenterIntent: ParsedSafetyCenterIntent = - requireActivity().getIntent().toSafetyCenterIntent() + requireActivity().intent.toSafetyCenterIntent() val isQsFragment = getArguments()?.getBoolean(QUICK_SETTINGS_SAFETY_CENTER_FRAGMENT, false) ?: false collapsableIssuesCardHelper = @@ -120,7 +120,7 @@ abstract class SafetyCenterFragment : PreferenceFragmentCompat() { override fun onStart() { super.onStart() configureInteractionLogger() - safetyCenterViewModel.interactionLogger.record(Action.SAFETY_CENTER_VIEWED) + logSafetyCenterViewedEvent() } override fun onResume() { @@ -162,6 +162,26 @@ abstract class SafetyCenterFragment : PreferenceFragmentCompat() { abstract fun configureInteractionLogger() + private fun logSafetyCenterViewedEvent() { + // If Safety Center was opened due to an associated notification click (i.e. intent has an + // associated issue), record that issue's metadata on the SAFETY_CENTER_VIEWED event + val maybeIssueKey = requireActivity().intent.toSafetyCenterIntent().safetyCenterIssueKey + val maybeIssue = + maybeIssueKey?.let { + safetyCenterViewModel.getCurrentSafetyCenterDataAsUiData().getMatchingIssue(it) + } + + if (maybeIssue == null) { + safetyCenterViewModel.interactionLogger.record(Action.SAFETY_CENTER_VIEWED) + } else { + safetyCenterViewModel.interactionLogger.recordForIssue( + Action.SAFETY_CENTER_VIEWED, + maybeIssue, + isDismissed = false + ) + } + } + private fun displayErrorDetails(errorDetails: SafetyCenterErrorDetails?) { if (errorDetails == null) return Toast.makeText(requireContext(), errorDetails.errorMessage, Toast.LENGTH_LONG).show() diff --git a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/SafetyCenterUiData.kt b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/SafetyCenterUiData.kt index 239f9a377..69a315f08 100644 --- a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/SafetyCenterUiData.kt +++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/SafetyCenterUiData.kt @@ -16,6 +16,7 @@ package com.android.permissioncontroller.safetycenter.ui.model +import android.os.Build.VERSION_CODES.TIRAMISU import android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE import android.safetycenter.SafetyCenterData import android.safetycenter.SafetyCenterEntryGroup @@ -24,12 +25,21 @@ import android.safetycenter.SafetyCenterIssue import android.safetycenter.SafetyCenterIssue.ISSUE_SEVERITY_LEVEL_OK import androidx.annotation.RequiresApi import com.android.safetycenter.internaldata.SafetyCenterBundles.ISSUES_TO_GROUPS_BUNDLE_KEY +import com.android.safetycenter.internaldata.SafetyCenterIds +import com.android.safetycenter.internaldata.SafetyCenterIssueKey /** UI model representation of Safety Center Data */ data class SafetyCenterUiData( val safetyCenterData: SafetyCenterData, val resolvedIssues: Map<IssueId, ActionId> = emptyMap() ) { + @RequiresApi(TIRAMISU) + fun getMatchingIssue(issueKey: SafetyCenterIssueKey): SafetyCenterIssue? { + return safetyCenterData.issues.find { + SafetyCenterIds.issueIdFromString(it.id).safetyCenterIssueKey == issueKey + } + } + /** Returns the [SafetyCenterEntryGroup] corresponding to the provided ID */ @RequiresApi(UPSIDE_DOWN_CAKE) fun getMatchingGroup(groupId: String): SafetyCenterEntryGroup? { diff --git a/tests/hostside/safetycenter/helper-app/Android.bp b/tests/hostside/safetycenter/helper-app/Android.bp index cf4372d99..a05f8d2f3 100644 --- a/tests/hostside/safetycenter/helper-app/Android.bp +++ b/tests/hostside/safetycenter/helper-app/Android.bp @@ -30,6 +30,7 @@ android_test_helper_app { static_libs: [ "androidx.test.rules", "androidx.test.ext.junit", + "safety-center-pending-intents", "safety-center-test-util-lib", ], }
\ No newline at end of file diff --git a/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetyCenterInteractionLoggingHelperTests.kt b/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetyCenterInteractionLoggingHelperTests.kt index 784701b8a..f37479180 100644 --- a/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetyCenterInteractionLoggingHelperTests.kt +++ b/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetyCenterInteractionLoggingHelperTests.kt @@ -19,14 +19,21 @@ package android.safetycenter.hostside.device import android.content.Context import android.os.Bundle import android.safetycenter.SafetyCenterManager.EXTRA_SAFETY_SOURCES_GROUP_ID +import android.safetycenter.SafetyCenterManager.EXTRA_SAFETY_SOURCE_ID +import android.safetycenter.SafetyCenterManager.EXTRA_SAFETY_SOURCE_ISSUE_ID import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import com.android.safetycenter.testing.SafetyCenterActivityLauncher.launchSafetyCenterActivity +import com.android.safetycenter.testing.SafetyCenterActivityLauncher.launchSafetyCenterQsActivity import com.android.safetycenter.testing.SafetyCenterActivityLauncher.openPageAndExit import com.android.safetycenter.testing.SafetyCenterFlags import com.android.safetycenter.testing.SafetyCenterTestConfigs +import com.android.safetycenter.testing.SafetyCenterTestConfigs.Companion.SINGLE_SOURCE_ID import com.android.safetycenter.testing.SafetyCenterTestHelper import com.android.safetycenter.testing.SafetyCenterTestRule +import com.android.safetycenter.testing.SafetySourceTestData +import com.android.safetycenter.testing.SafetySourceTestData.Companion.INFORMATION_ISSUE_ID +import com.android.safetycenter.testing.UiTestHelper.waitAllTextDisplayed import org.junit.Before import org.junit.Rule import org.junit.Test @@ -47,6 +54,7 @@ class SafetyCenterInteractionLoggingHelperTests { private val context: Context = ApplicationProvider.getApplicationContext() private val safetyCenterTestHelper = SafetyCenterTestHelper(context) private val safetyCenterTestConfigs = SafetyCenterTestConfigs(context) + private val safetySourceTestData = SafetySourceTestData(context) @get:Rule val safetyCenterTestRule = SafetyCenterTestRule(safetyCenterTestHelper) @@ -61,6 +69,34 @@ class SafetyCenterInteractionLoggingHelperTests { } @Test + fun openSafetyCenterFullFromQs() { + safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig) + safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, safetySourceTestData.informationWithIssue) + + context.launchSafetyCenterQsActivity { + openPageAndExit("Settings") { waitAllTextDisplayed(safetySourceTestData.informationIssue.title) } + } + } + + @Test + fun openSafetyCenterWithIssueIntent() { + safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig) + + safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, safetySourceTestData.informationWithIssue) + + val extras = Bundle() + extras.putString(EXTRA_SAFETY_SOURCE_ID, SINGLE_SOURCE_ID) + extras.putString(EXTRA_SAFETY_SOURCE_ISSUE_ID, INFORMATION_ISSUE_ID) + + context.launchSafetyCenterActivity(extras) {} + } + + @Test + fun openSafetyCenterQs() { + context.launchSafetyCenterQsActivity {} + } + + @Test fun openSubpageFromIntentExtra() { val config = safetyCenterTestConfigs.singleSourceConfig safetyCenterTestHelper.setConfig(config) diff --git a/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetyCenterNotificationLoggingHelperTests.kt b/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetyCenterNotificationLoggingHelperTests.kt index 458516379..dc3cb3fc2 100644 --- a/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetyCenterNotificationLoggingHelperTests.kt +++ b/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetyCenterNotificationLoggingHelperTests.kt @@ -21,12 +21,16 @@ import android.safetycenter.SafetySourceData import android.safetycenter.SafetySourceIssue import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.android.safetycenter.pendingintents.PendingIntentSender +import com.android.safetycenter.testing.SafetyCenterActivityLauncher import com.android.safetycenter.testing.SafetyCenterFlags import com.android.safetycenter.testing.SafetyCenterTestConfigs import com.android.safetycenter.testing.SafetyCenterTestConfigs.Companion.SINGLE_SOURCE_ID import com.android.safetycenter.testing.SafetyCenterTestHelper import com.android.safetycenter.testing.SafetyCenterTestRule import com.android.safetycenter.testing.SafetySourceTestData +import com.android.safetycenter.testing.StatusBarNotificationWithChannel +import com.android.safetycenter.testing.TestNotificationListener import org.junit.Before import org.junit.Rule import org.junit.Test @@ -49,7 +53,9 @@ class SafetyCenterNotificationLoggingHelperTests { private val safetySourceTestData = SafetySourceTestData(context) private val safetyCenterTestConfigs = SafetyCenterTestConfigs(context) - @get:Rule val safetyCenterTestRule = SafetyCenterTestRule(safetyCenterTestHelper) + @get:Rule + val safetyCenterTestRule = + SafetyCenterTestRule(safetyCenterTestHelper, withNotifications = true) @Before fun setUp() { @@ -64,6 +70,13 @@ class SafetyCenterNotificationLoggingHelperTests { safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, newTestDataWithNotifiableIssue()) } + @Test + fun openSafetyCenterFromNotification() { + safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, newTestDataWithNotifiableIssue()) + + sendContentPendingIntent(TestNotificationListener.waitForSingleNotification()) + } + private fun newTestDataWithNotifiableIssue(): SafetySourceData = safetySourceTestData .defaultCriticalDataBuilder() @@ -74,4 +87,17 @@ class SafetyCenterNotificationLoggingHelperTests { .build() ) .build() + + companion object { + private fun sendContentPendingIntent( + statusBarNotificationWithChannel: StatusBarNotificationWithChannel + ) { + val contentIntent = + statusBarNotificationWithChannel.statusBarNotification.notification.contentIntent + SafetyCenterActivityLauncher.executeBlockAndExit( + launchActivity = { PendingIntentSender.send(contentIntent) }, + block = {} // No action required + ) + } + } } diff --git a/tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetyCenterInteractionLoggingHostTest.kt b/tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetyCenterInteractionLoggingHostTest.kt index 5fe9e0a2a..91222d045 100644 --- a/tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetyCenterInteractionLoggingHostTest.kt +++ b/tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetyCenterInteractionLoggingHostTest.kt @@ -24,10 +24,13 @@ import com.android.compatibility.common.util.ApiLevelUtil import com.android.os.AtomsProto.Atom import com.android.os.AtomsProto.SafetyCenterInteractionReported import com.android.os.AtomsProto.SafetyCenterInteractionReported.Action +import com.android.os.AtomsProto.SafetyCenterInteractionReported.NavigationSource import com.android.os.AtomsProto.SafetyCenterInteractionReported.ViewType import com.android.tradefed.testtype.DeviceJUnit4ClassRunner import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test import com.google.common.truth.Truth.assertThat +import java.math.BigInteger +import java.security.MessageDigest import org.junit.After import org.junit.Assume.assumeTrue import org.junit.Before @@ -67,15 +70,76 @@ class SafetyCenterInteractionLoggingHostTest : BaseHostJUnit4Test() { val safetyCenterViewedAtoms = getInteractionReportedAtoms(Action.SAFETY_CENTER_VIEWED) - assertThat(safetyCenterViewedAtoms).isNotEmpty() + assertThat(safetyCenterViewedAtoms).hasSize(1) + with(safetyCenterViewedAtoms.first()) { + assertThat(navigationSource).isEqualTo(NavigationSource.SOURCE_UNKNOWN) + assertThat(viewType).isEqualTo(ViewType.FULL) + } } @Test - fun sendNotification_recordsNotificationPostedEvent() { + fun openSafetyCenterQs_recordsSafetyCenterViewedEvent() { + helperAppRule.runTest(TEST_CLASS_NAME, "openSafetyCenterQs") + + val safetyCenterViewedAtoms = getInteractionReportedAtoms(Action.SAFETY_CENTER_VIEWED) + + assertThat(safetyCenterViewedAtoms).hasSize(1) + with(safetyCenterViewedAtoms.first()) { + assertThat(navigationSource).isEqualTo(NavigationSource.QUICK_SETTINGS_TILE) + assertThat(viewType).isEqualTo(ViewType.QUICK_SETTINGS) + } + } + + @Test + fun openSafetyCenterFullFromQs_recordsViewEventWithCorrectSource() { + helperAppRule.runTest(TEST_CLASS_NAME, "openSafetyCenterFullFromQs") + + val safetyCenterViewedAtoms = getInteractionReportedAtoms(Action.SAFETY_CENTER_VIEWED) + + val viewTypesToNavSources = + safetyCenterViewedAtoms.associate { Pair(it.viewType, it.navigationSource) } + assertThat(viewTypesToNavSources) + .containsEntry(ViewType.FULL, NavigationSource.QUICK_SETTINGS_TILE) + } + + @Test + fun openSafetyCenterWithIssueIntent_recordsViewEventWithAssociatedIssueMetadata() { + helperAppRule.runTest(TEST_CLASS_NAME, testMethodName = "openSafetyCenterWithIssueIntent") + + val safetyCenterViewedAtoms = getInteractionReportedAtoms(Action.SAFETY_CENTER_VIEWED) + + assertThat(safetyCenterViewedAtoms).hasSize(1) + with(safetyCenterViewedAtoms.first()) { + assertThat(navigationSource).isEqualTo(NavigationSource.NOTIFICATION) + assertThat(encodedSafetySourceId).isEqualTo(ENCODED_SINGLE_SOURCE_ID) + assertThat(encodedIssueTypeId).isEqualTo(ENCODED_ISSUE_TYPE_ID) + } + } + + @Test + fun openSafetyCenterWithNotification_recordsViewEventWithAssociatedIssueMetadata() { assumeAtLeastUpsideDownCake("Safety Center notification APIs require Android U+") helperAppRule.runTest( testClassName = ".SafetyCenterNotificationLoggingHelperTests", + testMethodName = "openSafetyCenterFromNotification" + ) + + val safetyCenterViewedAtoms = getInteractionReportedAtoms(Action.SAFETY_CENTER_VIEWED) + + assertThat(safetyCenterViewedAtoms).hasSize(1) + with(safetyCenterViewedAtoms.first()) { + assertThat(navigationSource).isEqualTo(NavigationSource.NOTIFICATION) + assertThat(encodedSafetySourceId).isEqualTo(ENCODED_SINGLE_SOURCE_ID) + assertThat(encodedIssueTypeId).isEqualTo(ENCODED_ISSUE_TYPE_ID) + } + } + + @Test + fun sendNotification_recordsNotificationPostedEvent() { + assumeAtLeastUpsideDownCake("Safety Center notification APIs require Android U+") + helperAppRule.runTest( + testClassName = ".SafetyCenterNotificationLoggingHelperTests", testMethodName = "sendNotification" ) @@ -97,8 +161,7 @@ class SafetyCenterInteractionLoggingHostTest : BaseHostJUnit4Test() { assertThat(safetyCenterViewedAtoms).hasSize(1) with(safetyCenterViewedAtoms.first()) { assertThat(viewType).isEqualTo(ViewType.SUBPAGE) - assertThat(navigationSource) - .isEqualTo(SafetyCenterInteractionReported.NavigationSource.SOURCE_UNKNOWN) + assertThat(navigationSource).isEqualTo(NavigationSource.SOURCE_UNKNOWN) assertThat(sessionId).isNotNull() } } @@ -113,8 +176,7 @@ class SafetyCenterInteractionLoggingHostTest : BaseHostJUnit4Test() { val subpageViewedEvent = safetyCenterViewedAtoms.find { it.viewType == ViewType.SUBPAGE } assertThat(subpageViewedEvent).isNotNull() - assertThat(subpageViewedEvent!!.navigationSource) - .isEqualTo(SafetyCenterInteractionReported.NavigationSource.SAFETY_CENTER) + assertThat(subpageViewedEvent!!.navigationSource).isEqualTo(NavigationSource.SAFETY_CENTER) assertThat(safetyCenterViewedAtoms.map { it.sessionId }.distinct()).hasSize(1) } @@ -129,8 +191,7 @@ class SafetyCenterInteractionLoggingHostTest : BaseHostJUnit4Test() { assertThat(safetyCenterViewedAtoms).hasSize(1) with(safetyCenterViewedAtoms.first()) { assertThat(viewType).isEqualTo(ViewType.SUBPAGE) - assertThat(navigationSource) - .isEqualTo(SafetyCenterInteractionReported.NavigationSource.SETTINGS) + assertThat(navigationSource).isEqualTo(NavigationSource.SETTINGS) assertThat(sessionId).isNotNull() } } @@ -148,5 +209,27 @@ class SafetyCenterInteractionLoggingHostTest : BaseHostJUnit4Test() { private companion object { const val TEST_CLASS_NAME = ".SafetyCenterInteractionLoggingHelperTests" + + // LINT.IfChange(single_source_id) + val ENCODED_SINGLE_SOURCE_ID = encodeId("test_single_source_id") + // LINT.ThenChange(/tests/utils/safetycenter/java/com/android/safetycenter/testing/SafetyCenterTestConfigs.kt:issue_type_id) + + // LINT.IfChange(issue_type_id) + val ENCODED_ISSUE_TYPE_ID = encodeId("issue_type_id") + // LINT.ThenChange(/tests/utils/safetycenter/java/com/android/safetycenter/testing/SafetySourceTestData.kt:issue_type_id) + + /** + * Encodes a string into an long ID. The ID is a SHA-256 of the string, truncated to 64 + * bits. + */ + fun encodeId(id: String?): Long { + if (id == null) return 0 + + val digest = MessageDigest.getInstance("MD5") + digest.update(id.toByteArray()) + + // Truncate to the size of a long + return BigInteger(digest.digest()).toLong() + } } } diff --git a/tests/utils/safetycenter/java/com/android/safetycenter/testing/SafetyCenterTestConfigs.kt b/tests/utils/safetycenter/java/com/android/safetycenter/testing/SafetyCenterTestConfigs.kt index 2af2b391a..b0d209fcc 100644 --- a/tests/utils/safetycenter/java/com/android/safetycenter/testing/SafetyCenterTestConfigs.kt +++ b/tests/utils/safetycenter/java/com/android/safetycenter/testing/SafetyCenterTestConfigs.kt @@ -856,7 +856,9 @@ class SafetyCenterTestConfigs(private val context: Context) { * ID of the only source provided in [singleSourceConfig], [severityZeroConfig] and * [noPageOpenConfig]. */ + // LINT.IfChange(single_source_id) const val SINGLE_SOURCE_ID = "test_single_source_id" + // LINT.ThenChange(/tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetyCenterInteractionLoggingHostTest.kt:single_source_id) /** ID of the only source provided in [singleSourceAllProfileConfig]. */ const val SINGLE_SOURCE_ALL_PROFILE_ID = "test_single_source_all_profile_id" diff --git a/tests/utils/safetycenter/java/com/android/safetycenter/testing/SafetySourceTestData.kt b/tests/utils/safetycenter/java/com/android/safetycenter/testing/SafetySourceTestData.kt index 2c4f856bb..66be55fa8 100644 --- a/tests/utils/safetycenter/java/com/android/safetycenter/testing/SafetySourceTestData.kt +++ b/tests/utils/safetycenter/java/com/android/safetycenter/testing/SafetySourceTestData.kt @@ -802,7 +802,9 @@ class SafetySourceTestData(private val context: Context) { const val CRITICAL_ISSUE_ACTION_ID = "critical_issue_action_id" /** Issue type ID for all the issues in this file */ + // LINT.IfChange(issue_type_id) const val ISSUE_TYPE_ID = "issue_type_id" + // LINT.ThenChange(/tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetyCenterInteractionLoggingHostTest.kt:issue_type_id) const val CONFIRMATION_TITLE = "Confirmation title" const val CONFIRMATION_TEXT = "Confirmation text" |