Merge changes I4c813a35,I9bedb58a
* changes:
Toggle Security and Privacy entries depending on SafetyCenter status.
Add SafetyCenter entry to Settings.
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 083d8b9..310ed38 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -110,6 +110,7 @@
<uses-permission android:name="android.permission.MANAGE_APP_HIBERNATION" />
<uses-permission android:name="android.permission.LAUNCH_MULTI_PANE_SETTINGS_DEEP_LINK" />
<uses-permission android:name="android.permission.ALLOW_PLACE_IN_MULTI_PANE_SETTINGS" />
+ <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<application
android:name=".SettingsApplication"
@@ -146,10 +147,11 @@
<!-- Activity for launching deep link page in 2-pane. -->
<activity android:name=".homepage.DeepLinkHomepageActivity"
android:label="@string/settings_label_launcher"
- android:theme="@style/Theme.Settings.Home"
+ android:theme="@style/Theme.Settings.Home.DeepLink"
android:taskAffinity=""
android:launchMode="singleTask"
android:exported="true"
+ android:enabled="false"
android:configChanges="orientation|keyboard|keyboardHidden|screenSize|screenLayout"
android:permission="android.permission.LAUNCH_MULTI_PANE_SETTINGS_DEEP_LINK">
<intent-filter>
@@ -162,7 +164,7 @@
<activity android:name=".homepage.SliceDeepLinkHomepageActivity"
android:label="@string/settings_label_launcher"
- android:theme="@style/Theme.Settings.Home"
+ android:theme="@style/Theme.Settings.Home.DeepLink"
android:taskAffinity=""
android:launchMode="singleTask"
android:exported="false"
@@ -196,7 +198,6 @@
</receiver>
<activity android:name=".SubSettings"
- android:configChanges="orientation|keyboard|keyboardHidden|screenSize|screenLayout|smallestScreenSize"
android:theme="@style/Theme.SubSettings" />
<activity android:name=".Settings$CreateShortcutActivity"
@@ -241,6 +242,11 @@
android:exported="true"
android:launchMode="singleTask"
android:configChanges="orientation|screenSize|keyboardHidden">
+ <!-- Note: Since the framework does not support the multiple requests of network scan
+ from the UI, this singleTask can protect that there is only one
+ Settings$NetworkSelectActivity which can request the network scan.
+ If removing the "singleTask" in the future, please also modify the
+ Settings$NetworkSelectActivity's structure. -->
<intent-filter android:priority="1">
<!-- Displays the MobileNetworkActivity and opt-in dialog for capability discovery. -->
<action android:name="android.telephony.ims.action.SHOW_CAPABILITY_DISCOVERY_OPT_IN" />
@@ -307,6 +313,7 @@
<receiver android:name=".search.SearchStateReceiver"
android:exported="true"
+ android:enabled="false"
android:permission="android.permission.READ_SEARCH_INDEXABLES">
<intent-filter>
<action android:name="com.android.settings.SEARCH_START"/>
@@ -370,6 +377,16 @@
</activity>
<activity
+ android:name="Settings$NetworkSelectActivity"
+ android:label="@string/choose_network_title"
+ android:configChanges="orientation|keyboard|keyboardHidden|screenSize|screenLayout|smallestScreenSize">
+ <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
+ android:value="com.android.settings.network.telephony.NetworkSelectSettings" />
+ <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
+ android:value="true" />
+ </activity>
+
+ <activity
android:name="Settings$WifiDetailsSettingsActivity"
android:label="@string/wifi_details_title"
android:icon="@drawable/ic_homepage_network"
@@ -659,12 +676,12 @@
<activity android:name=".network.telephony.ToggleSubscriptionDialogActivity"
android:exported="false"
android:permission="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS"
- android:theme="@*android:style/Theme.DeviceDefault.Dialog.Alert.DayNight" />
+ android:theme="@style/Theme.AlertDialog"/>
<activity android:name=".network.telephony.DeleteEuiccSubscriptionDialogActivity"
android:exported="false"
android:permission="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS"
- android:theme="@*android:style/Theme.DeviceDefault.Dialog.Alert.DayNight" />
+ android:theme="@style/Theme.AlertDialog"/>
<activity
android:name="Settings$TetherSettingsActivity"
@@ -1269,6 +1286,23 @@
</activity>
<activity
+ android:name=".Settings$BlueToothPairingActivity"
+ android:label="@string/bluetooth_pairing_page_title"
+ android:permission="android.permission.BLUETOOTH_SCAN"
+ android:exported="true">
+ <intent-filter android:priority="1">
+ <action android:name="android.settings.BLUETOOTH_PAIRING_SETTINGS" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
+ android:value="com.android.settings.bluetooth.BluetoothPairingDetail" />
+ <meta-data android:name="com.android.settings.HIGHLIGHT_MENU_KEY"
+ android:value="@string/menu_key_connected_devices"/>
+ <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
+ android:value="true" />
+ </activity>
+
+ <activity
android:name="SettingsLicenseActivity"
android:label="@string/settings_license_activity_title"
android:exported="true"
@@ -2104,8 +2138,7 @@
android:screenOrientation="portrait"/>
<activity android:name=".biometrics.BiometricHandoffActivity"
- android:exported="false"
- android:screenOrientation="portrait"/>
+ android:exported="false"/>
<!-- Must not be exported -->
<activity android:name=".biometrics.BiometricEnrollActivity$InternalActivity"
@@ -4230,14 +4263,14 @@
android:exported="false"
android:permission="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS"
android:launchMode="singleInstance"
- android:theme="@*android:style/Theme.DeviceDefault.Dialog.Alert.DayNight" />
+ android:theme="@style/Theme.AlertDialog"/>
<activity
android:name=".sim.DsdsDialogActivity"
android:exported="false"
android:permission="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS"
android:launchMode="singleInstance"
- android:theme="@*android:style/Theme.DeviceDefault.Dialog.Alert.DayNight" />
+ android:theme="@style/Theme.AlertDialog"/>
<service android:name=".sim.SimNotificationService"
android:permission="android.permission.BIND_JOB_SERVICE" />
diff --git a/res/layout/accessibility_launch_activity_preference.xml b/res/layout/accessibility_launch_activity_preference.xml
new file mode 100644
index 0000000..772bb84
--- /dev/null
+++ b/res/layout/accessibility_launch_activity_preference.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2021 The Android Open Source Project
+
+ 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
+
+ http://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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:minHeight="@dimen/settingslib_min_switch_bar_height"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_margin="@dimen/settingslib_switchbar_margin"
+ android:paddingStart="@dimen/settingslib_switchbar_padding_left"
+ android:paddingEnd="@dimen/settingslib_switchbar_padding_right"
+ android:background="@drawable/settingslib_switch_bar_bg_on">
+
+ <TextView
+ android:id="@android:id/title"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_marginEnd="@dimen/settingslib_switch_title_margin"
+ android:layout_marginVertical="@dimen/settingslib_switch_title_margin"
+ android:layout_gravity="center_vertical"
+ android:ellipsize="end"
+ android:textAppearance="?android:attr/textAppearanceListItem"
+ style="@style/MainSwitchText.Settingslib" />
+</LinearLayout>
diff --git a/res/layout/biometric_handoff.xml b/res/layout/biometric_handoff.xml
index 4861568..7da4917 100644
--- a/res/layout/biometric_handoff.xml
+++ b/res/layout/biometric_handoff.xml
@@ -17,8 +17,8 @@
<com.google.android.setupdesign.GlifLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- style="?attr/face_layout_theme"
android:id="@+id/setup_wizard_layout"
android:layout_width="match_parent"
- android:layout_height="match_parent">
-</com.google.android.setupdesign.GlifLayout>
\ No newline at end of file
+ android:layout_height="match_parent"
+ android:icon="@drawable/ic_lock">
+</com.google.android.setupdesign.GlifLayout>
diff --git a/res/layout/font_size_preview.xml b/res/layout/font_size_preview.xml
index 2b1773b..f916ac4 100644
--- a/res/layout/font_size_preview.xml
+++ b/res/layout/font_size_preview.xml
@@ -26,6 +26,7 @@
android:layout_height="wrap_content">
<LinearLayout
+ android:id="@+id/font_size_preview_text_group"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="16dp"
diff --git a/res/layout/sim_confirm_dialog_multiple_enabled_profiles_supported.xml b/res/layout/sim_confirm_dialog_multiple_enabled_profiles_supported.xml
new file mode 100644
index 0000000..4404482
--- /dev/null
+++ b/res/layout/sim_confirm_dialog_multiple_enabled_profiles_supported.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+ 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
+
+ http://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.
+-->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ style="@style/Theme.Material3.DayNight.Dialog.Alert">
+ <TextView
+ android:id="@+id/msg"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+ <ListView
+ android:id="@+id/carrier_list"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:minWidth="56dp"
+ android:gravity="start|top"
+ android:orientation="horizontal"
+ android:paddingEnd="12dp"
+ android:paddingTop="16dp"
+ android:paddingBottom="4dp"
+ android:baselineAligned="true">
+ <ImageView
+ android:src="@drawable/ic_info_outline_24dp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:tint="?android:attr/textColorTertiary"/>
+
+ <TextView
+ android:id="@+id/info_outline"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingTop="16dp"
+ android:paddingBottom="8dp"
+ android:text="@string/sim_action_switch_sub_dialog_info_outline_for_turning_off"
+ android:textColor="?android:attr/textColorSecondary" />
+ </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/suw_font_size_fragment.xml b/res/layout/suw_font_size_fragment.xml
index 0e03a69..898b9eb 100644
--- a/res/layout/suw_font_size_fragment.xml
+++ b/res/layout/suw_font_size_fragment.xml
@@ -75,12 +75,6 @@
android:contentDescription="@string/font_size_make_larger_desc"
style="@style/screen_size_imageview_style"/>
</LinearLayout>
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/font_size_summary"
- android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"/>
</LinearLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
diff --git a/res/layout/suw_screen_zoom_fragment.xml b/res/layout/suw_screen_zoom_fragment.xml
index 0747381..369ff14 100644
--- a/res/layout/suw_screen_zoom_fragment.xml
+++ b/res/layout/suw_screen_zoom_fragment.xml
@@ -74,12 +74,6 @@
android:contentDescription="@string/screen_zoom_make_larger_desc"
style="@style/screen_size_imageview_style"/>
</LinearLayout>
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/screen_zoom_summary"
- android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"/>
</LinearLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
diff --git a/res/layout/wifi_calling_settings_preferences.xml b/res/layout/wifi_calling_settings_preferences.xml
index 98acd95..9a6cbe6 100644
--- a/res/layout/wifi_calling_settings_preferences.xml
+++ b/res/layout/wifi_calling_settings_preferences.xml
@@ -29,16 +29,11 @@
<FrameLayout
android:id="@android:id/tabcontent"
- android:layout_width="0dip"
- android:layout_height="0dip" />
-
- <FrameLayout
- android:id="@+id/prefs_container"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1"
- android:clipChildren="false"
- android:clipToPadding="false"
+ android:clipChildren="true"
+ android:clipToPadding="true"
android:smoothScrollbar="false" />
</LinearLayout>
diff --git a/res/raw/udfps_edu_lottie.json b/res/raw/udfps_edu_lottie.json
index c13a02f..e012380 100644
--- a/res/raw/udfps_edu_lottie.json
+++ b/res/raw/udfps_edu_lottie.json
@@ -1,12485 +1 @@
-{
- "v": "5.7.13",
- "fr": 60,
- "ip": 0,
- "op": 541,
- "w": 300,
- "h": 289,
- "nm": "enrollment_edu_02",
- "ddd": 0,
- "assets": [],
- "layers": [
- {
- "ddd": 0,
- "ind": 1,
- "ty": 4,
- "nm": "fingerprint motion 8",
- "parent": 10,
- "sr": 1,
- "ks": {
- "o": {
- "a": 0,
- "k": 100,
- "ix": 11
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 10
- },
- "p": {
- "a": 0,
- "k": [
- -10.467,
- 814.892,
- 0
- ],
- "ix": 2,
- "l": 2
- },
- "a": {
- "a": 0,
- "k": [
- 22.5,
- 28.676,
- 0
- ],
- "ix": 1,
- "l": 2
- },
- "s": {
- "a": 0,
- "k": [
- 353.53,
- 353.53,
- 100
- ],
- "ix": 6,
- "l": 2
- }
- },
- "ao": 0,
- "shapes": [
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- 3.564,
- 0
- ],
- [
- 2.241,
- 1.694
- ]
- ],
- "o": [
- [
- -2.329,
- 2.012
- ],
- [
- -3.23,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- 8.7,
- -1.624
- ],
- [
- -0.335,
- 1.624
- ],
- [
- -8.7,
- -1.076
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541000007181,
- 0.705999995213,
- 0.972999961703,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 22.837,
- 48.229
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 1",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 1,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- -7.553,
- 0
- ],
- [
- 0,
- -6.83
- ]
- ],
- "o": [
- [
- -0.988,
- -2.577
- ],
- [
- 0,
- -6.83
- ],
- [
- 7.553,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- -12.247,
- 8.824
- ],
- [
- -13.235,
- 3.529
- ],
- [
- 0,
- -8.824
- ],
- [
- 13.235,
- 3.529
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541000007181,
- 0.705999995213,
- 0.972999961703,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 22.5,
- 30.441
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 2",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 2,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- 2.647,
- 0
- ],
- [
- 0.388,
- 2.294
- ],
- [
- 0,
- 0
- ],
- [
- 2.117,
- 0
- ],
- [
- -5.241,
- -1.482
- ]
- ],
- "o": [
- [
- 0,
- 0
- ],
- [
- 0,
- 2.629
- ],
- [
- -2.33,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- -0.353,
- -2.1
- ],
- [
- -7.624,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- 10.95,
- -1.756
- ],
- [
- 10.95,
- -1.244
- ],
- [
- 6.168,
- 3.538
- ],
- [
- 1.456,
- -0.45
- ],
- [
- 0.962,
- -3.415
- ],
- [
- -3.326,
- -7.05
- ],
- [
- -2.568,
- 7.05
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541000007181,
- 0.705999995213,
- 0.972999961703,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 24.786,
- 35.727
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 3",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 3,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- -6.618,
- 0
- ],
- [
- -2.665,
- -4.165
- ]
- ],
- "o": [
- [
- 2.665,
- -4.165
- ],
- [
- 6.618,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- -15,
- 3.529
- ],
- [
- 0,
- -3.529
- ],
- [
- 15,
- 3.529
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541000007181,
- 0.705999995213,
- 0.972999961703,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 22.5,
- 18.088
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 4",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 4,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- -3.53,
- 0
- ],
- [
- -2.859,
- -1.429
- ]
- ],
- "o": [
- [
- 2.859,
- -1.429
- ],
- [
- 3.529,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- -9.706,
- 1.12
- ],
- [
- 0,
- -1.12
- ],
- [
- 9.706,
- 1.12
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541000007181,
- 0.705999995213,
- 0.972999961703,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 22.5,
- 8.621
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 5",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 5,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "tm",
- "s": {
- "a": 1,
- "k": [
- {
- "i": {
- "x": [
- 0
- ],
- "y": [
- 1
- ]
- },
- "o": {
- "x": [
- 0.333
- ],
- "y": [
- 0
- ]
- },
- "t": 429,
- "s": [
- 100
- ]
- },
- {
- "t": 440,
- "s": [
- 0
- ]
- }
- ],
- "ix": 1
- },
- "e": {
- "a": 0,
- "k": 100,
- "ix": 2
- },
- "o": {
- "a": 0,
- "k": 0,
- "ix": 3
- },
- "m": 1,
- "ix": 6,
- "nm": "Trim Paths 1",
- "mn": "ADBE Vector Filter - Trim",
- "hd": false
- }
- ],
- "ip": 418,
- "op": 630,
- "st": 232,
- "bm": 0
- },
- {
- "ddd": 0,
- "ind": 2,
- "ty": 4,
- "nm": "fingerprint motion 7",
- "parent": 10,
- "sr": 1,
- "ks": {
- "o": {
- "a": 0,
- "k": 100,
- "ix": 11
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 10
- },
- "p": {
- "a": 0,
- "k": [
- -10.467,
- 814.892,
- 0
- ],
- "ix": 2,
- "l": 2
- },
- "a": {
- "a": 0,
- "k": [
- 22.5,
- 28.676,
- 0
- ],
- "ix": 1,
- "l": 2
- },
- "s": {
- "a": 0,
- "k": [
- 353.53,
- 353.53,
- 100
- ],
- "ix": 6,
- "l": 2
- }
- },
- "ao": 0,
- "shapes": [
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- 3.564,
- 0
- ],
- [
- 2.241,
- 1.694
- ]
- ],
- "o": [
- [
- -2.329,
- 2.012
- ],
- [
- -3.23,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- 8.7,
- -1.624
- ],
- [
- -0.335,
- 1.624
- ],
- [
- -8.7,
- -1.076
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541000007181,
- 0.705999995213,
- 0.972999961703,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 22.837,
- 48.229
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 1",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 1,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- -7.553,
- 0
- ],
- [
- 0,
- -6.83
- ]
- ],
- "o": [
- [
- -0.988,
- -2.577
- ],
- [
- 0,
- -6.83
- ],
- [
- 7.553,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- -12.247,
- 8.824
- ],
- [
- -13.235,
- 3.529
- ],
- [
- 0,
- -8.824
- ],
- [
- 13.235,
- 3.529
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541000007181,
- 0.705999995213,
- 0.972999961703,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 22.5,
- 30.441
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 2",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 2,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- 2.647,
- 0
- ],
- [
- 0.388,
- 2.294
- ],
- [
- 0,
- 0
- ],
- [
- 2.117,
- 0
- ],
- [
- -5.241,
- -1.482
- ]
- ],
- "o": [
- [
- 0,
- 0
- ],
- [
- 0,
- 2.629
- ],
- [
- -2.33,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- -0.353,
- -2.1
- ],
- [
- -7.624,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- 10.95,
- -1.756
- ],
- [
- 10.95,
- -1.244
- ],
- [
- 6.168,
- 3.538
- ],
- [
- 1.456,
- -0.45
- ],
- [
- 0.962,
- -3.415
- ],
- [
- -3.326,
- -7.05
- ],
- [
- -2.568,
- 7.05
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541000007181,
- 0.705999995213,
- 0.972999961703,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 24.786,
- 35.727
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 3",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 3,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- -6.618,
- 0
- ],
- [
- -2.665,
- -4.165
- ]
- ],
- "o": [
- [
- 2.665,
- -4.165
- ],
- [
- 6.618,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- -15,
- 3.529
- ],
- [
- 0,
- -3.529
- ],
- [
- 15,
- 3.529
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541000007181,
- 0.705999995213,
- 0.972999961703,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 22.5,
- 18.088
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 4",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 4,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- -3.53,
- 0
- ],
- [
- -2.859,
- -1.429
- ]
- ],
- "o": [
- [
- 2.859,
- -1.429
- ],
- [
- 3.529,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- -9.706,
- 1.12
- ],
- [
- 0,
- -1.12
- ],
- [
- 9.706,
- 1.12
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541000007181,
- 0.705999995213,
- 0.972999961703,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 22.5,
- 8.621
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 5",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 5,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "tm",
- "s": {
- "a": 0,
- "k": 0,
- "ix": 1
- },
- "e": {
- "a": 1,
- "k": [
- {
- "i": {
- "x": [
- 0.667
- ],
- "y": [
- 1
- ]
- },
- "o": {
- "x": [
- 0.333
- ],
- "y": [
- 0
- ]
- },
- "t": 380,
- "s": [
- 100
- ]
- },
- {
- "t": 394,
- "s": [
- 0
- ]
- }
- ],
- "ix": 2
- },
- "o": {
- "a": 0,
- "k": 0,
- "ix": 3
- },
- "m": 1,
- "ix": 6,
- "nm": "Trim Paths 1",
- "mn": "ADBE Vector Filter - Trim",
- "hd": false
- }
- ],
- "ip": 369,
- "op": 418,
- "st": 232,
- "bm": 0
- },
- {
- "ddd": 0,
- "ind": 3,
- "ty": 4,
- "nm": "fingerprint motion 6",
- "parent": 10,
- "sr": 1,
- "ks": {
- "o": {
- "a": 0,
- "k": 100,
- "ix": 11
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 10
- },
- "p": {
- "a": 0,
- "k": [
- -10.467,
- 814.892,
- 0
- ],
- "ix": 2,
- "l": 2
- },
- "a": {
- "a": 0,
- "k": [
- 22.5,
- 28.676,
- 0
- ],
- "ix": 1,
- "l": 2
- },
- "s": {
- "a": 0,
- "k": [
- 353.53,
- 353.53,
- 100
- ],
- "ix": 6,
- "l": 2
- }
- },
- "ao": 0,
- "shapes": [
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- 3.564,
- 0
- ],
- [
- 2.241,
- 1.694
- ]
- ],
- "o": [
- [
- -2.329,
- 2.012
- ],
- [
- -3.23,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- 8.7,
- -1.624
- ],
- [
- -0.335,
- 1.624
- ],
- [
- -8.7,
- -1.076
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541000007181,
- 0.705999995213,
- 0.972999961703,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 22.837,
- 48.229
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 1",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 1,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- -7.553,
- 0
- ],
- [
- 0,
- -6.83
- ]
- ],
- "o": [
- [
- -0.988,
- -2.577
- ],
- [
- 0,
- -6.83
- ],
- [
- 7.553,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- -12.247,
- 8.824
- ],
- [
- -13.235,
- 3.529
- ],
- [
- 0,
- -8.824
- ],
- [
- 13.235,
- 3.529
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541000007181,
- 0.705999995213,
- 0.972999961703,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 22.5,
- 30.441
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 2",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 2,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- 2.647,
- 0
- ],
- [
- 0.388,
- 2.294
- ],
- [
- 0,
- 0
- ],
- [
- 2.117,
- 0
- ],
- [
- -5.241,
- -1.482
- ]
- ],
- "o": [
- [
- 0,
- 0
- ],
- [
- 0,
- 2.629
- ],
- [
- -2.33,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- -0.353,
- -2.1
- ],
- [
- -7.624,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- 10.95,
- -1.756
- ],
- [
- 10.95,
- -1.244
- ],
- [
- 6.168,
- 3.538
- ],
- [
- 1.456,
- -0.45
- ],
- [
- 0.962,
- -3.415
- ],
- [
- -3.326,
- -7.05
- ],
- [
- -2.568,
- 7.05
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541000007181,
- 0.705999995213,
- 0.972999961703,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 24.786,
- 35.727
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 3",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 3,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- -6.618,
- 0
- ],
- [
- -2.665,
- -4.165
- ]
- ],
- "o": [
- [
- 2.665,
- -4.165
- ],
- [
- 6.618,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- -15,
- 3.529
- ],
- [
- 0,
- -3.529
- ],
- [
- 15,
- 3.529
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541000007181,
- 0.705999995213,
- 0.972999961703,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 22.5,
- 18.088
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 4",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 4,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- -3.53,
- 0
- ],
- [
- -2.859,
- -1.429
- ]
- ],
- "o": [
- [
- 2.859,
- -1.429
- ],
- [
- 3.529,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- -9.706,
- 1.12
- ],
- [
- 0,
- -1.12
- ],
- [
- 9.706,
- 1.12
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541000007181,
- 0.705999995213,
- 0.972999961703,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 22.5,
- 8.621
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 5",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 5,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "tm",
- "s": {
- "a": 1,
- "k": [
- {
- "i": {
- "x": [
- 0
- ],
- "y": [
- 1
- ]
- },
- "o": {
- "x": [
- 0.333
- ],
- "y": [
- 0
- ]
- },
- "t": 335,
- "s": [
- 100
- ]
- },
- {
- "t": 348,
- "s": [
- 0
- ]
- }
- ],
- "ix": 1
- },
- "e": {
- "a": 0,
- "k": 100,
- "ix": 2
- },
- "o": {
- "a": 0,
- "k": 0,
- "ix": 3
- },
- "m": 1,
- "ix": 6,
- "nm": "Trim Paths 1",
- "mn": "ADBE Vector Filter - Trim",
- "hd": false
- }
- ],
- "ip": 324,
- "op": 369,
- "st": 131,
- "bm": 0
- },
- {
- "ddd": 0,
- "ind": 4,
- "ty": 4,
- "nm": "fingerprint motion 5",
- "parent": 10,
- "sr": 1,
- "ks": {
- "o": {
- "a": 0,
- "k": 100,
- "ix": 11
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 10
- },
- "p": {
- "a": 0,
- "k": [
- -10.467,
- 814.892,
- 0
- ],
- "ix": 2,
- "l": 2
- },
- "a": {
- "a": 0,
- "k": [
- 22.5,
- 28.676,
- 0
- ],
- "ix": 1,
- "l": 2
- },
- "s": {
- "a": 0,
- "k": [
- 353.53,
- 353.53,
- 100
- ],
- "ix": 6,
- "l": 2
- }
- },
- "ao": 0,
- "shapes": [
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- 3.564,
- 0
- ],
- [
- 2.241,
- 1.694
- ]
- ],
- "o": [
- [
- -2.329,
- 2.012
- ],
- [
- -3.23,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- 8.7,
- -1.624
- ],
- [
- -0.335,
- 1.624
- ],
- [
- -8.7,
- -1.076
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541000007181,
- 0.705999995213,
- 0.972999961703,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 22.837,
- 48.229
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 1",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 1,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- -7.553,
- 0
- ],
- [
- 0,
- -6.83
- ]
- ],
- "o": [
- [
- -0.988,
- -2.577
- ],
- [
- 0,
- -6.83
- ],
- [
- 7.553,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- -12.247,
- 8.824
- ],
- [
- -13.235,
- 3.529
- ],
- [
- 0,
- -8.824
- ],
- [
- 13.235,
- 3.529
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541000007181,
- 0.705999995213,
- 0.972999961703,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 22.5,
- 30.441
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 2",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 2,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- 2.647,
- 0
- ],
- [
- 0.388,
- 2.294
- ],
- [
- 0,
- 0
- ],
- [
- 2.117,
- 0
- ],
- [
- -5.241,
- -1.482
- ]
- ],
- "o": [
- [
- 0,
- 0
- ],
- [
- 0,
- 2.629
- ],
- [
- -2.33,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- -0.353,
- -2.1
- ],
- [
- -7.624,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- 10.95,
- -1.756
- ],
- [
- 10.95,
- -1.244
- ],
- [
- 6.168,
- 3.538
- ],
- [
- 1.456,
- -0.45
- ],
- [
- 0.962,
- -3.415
- ],
- [
- -3.326,
- -7.05
- ],
- [
- -2.568,
- 7.05
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541000007181,
- 0.705999995213,
- 0.972999961703,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 24.786,
- 35.727
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 3",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 3,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- -6.618,
- 0
- ],
- [
- -2.665,
- -4.165
- ]
- ],
- "o": [
- [
- 2.665,
- -4.165
- ],
- [
- 6.618,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- -15,
- 3.529
- ],
- [
- 0,
- -3.529
- ],
- [
- 15,
- 3.529
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541000007181,
- 0.705999995213,
- 0.972999961703,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 22.5,
- 18.088
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 4",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 4,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- -3.53,
- 0
- ],
- [
- -2.859,
- -1.429
- ]
- ],
- "o": [
- [
- 2.859,
- -1.429
- ],
- [
- 3.529,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- -9.706,
- 1.12
- ],
- [
- 0,
- -1.12
- ],
- [
- 9.706,
- 1.12
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541000007181,
- 0.705999995213,
- 0.972999961703,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 22.5,
- 8.621
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 5",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 5,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "tm",
- "s": {
- "a": 0,
- "k": 0,
- "ix": 1
- },
- "e": {
- "a": 1,
- "k": [
- {
- "i": {
- "x": [
- 0.667
- ],
- "y": [
- 1
- ]
- },
- "o": {
- "x": [
- 0.333
- ],
- "y": [
- 0
- ]
- },
- "t": 285,
- "s": [
- 100
- ]
- },
- {
- "t": 299,
- "s": [
- 0
- ]
- }
- ],
- "ix": 2
- },
- "o": {
- "a": 0,
- "k": 0,
- "ix": 3
- },
- "m": 1,
- "ix": 6,
- "nm": "Trim Paths 1",
- "mn": "ADBE Vector Filter - Trim",
- "hd": false
- }
- ],
- "ip": 278,
- "op": 324,
- "st": 131,
- "bm": 0
- },
- {
- "ddd": 0,
- "ind": 5,
- "ty": 4,
- "nm": "fingerprint motion 4",
- "parent": 10,
- "sr": 1,
- "ks": {
- "o": {
- "a": 0,
- "k": 100,
- "ix": 11
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 10
- },
- "p": {
- "a": 0,
- "k": [
- -10.467,
- 814.892,
- 0
- ],
- "ix": 2,
- "l": 2
- },
- "a": {
- "a": 0,
- "k": [
- 22.5,
- 28.676,
- 0
- ],
- "ix": 1,
- "l": 2
- },
- "s": {
- "a": 0,
- "k": [
- 353.53,
- 353.53,
- 100
- ],
- "ix": 6,
- "l": 2
- }
- },
- "ao": 0,
- "shapes": [
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- 3.564,
- 0
- ],
- [
- 2.241,
- 1.694
- ]
- ],
- "o": [
- [
- -2.329,
- 2.012
- ],
- [
- -3.23,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- 8.7,
- -1.624
- ],
- [
- -0.335,
- 1.624
- ],
- [
- -8.7,
- -1.076
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541000007181,
- 0.705999995213,
- 0.972999961703,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 22.837,
- 48.229
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 1",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 1,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- -7.553,
- 0
- ],
- [
- 0,
- -6.83
- ]
- ],
- "o": [
- [
- -0.988,
- -2.577
- ],
- [
- 0,
- -6.83
- ],
- [
- 7.553,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- -12.247,
- 8.824
- ],
- [
- -13.235,
- 3.529
- ],
- [
- 0,
- -8.824
- ],
- [
- 13.235,
- 3.529
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541000007181,
- 0.705999995213,
- 0.972999961703,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 22.5,
- 30.441
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 2",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 2,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- 2.647,
- 0
- ],
- [
- 0.388,
- 2.294
- ],
- [
- 0,
- 0
- ],
- [
- 2.117,
- 0
- ],
- [
- -5.241,
- -1.482
- ]
- ],
- "o": [
- [
- 0,
- 0
- ],
- [
- 0,
- 2.629
- ],
- [
- -2.33,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- -0.353,
- -2.1
- ],
- [
- -7.624,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- 10.95,
- -1.756
- ],
- [
- 10.95,
- -1.244
- ],
- [
- 6.168,
- 3.538
- ],
- [
- 1.456,
- -0.45
- ],
- [
- 0.962,
- -3.415
- ],
- [
- -3.326,
- -7.05
- ],
- [
- -2.568,
- 7.05
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541000007181,
- 0.705999995213,
- 0.972999961703,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 24.786,
- 35.727
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 3",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 3,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- -6.618,
- 0
- ],
- [
- -2.665,
- -4.165
- ]
- ],
- "o": [
- [
- 2.665,
- -4.165
- ],
- [
- 6.618,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- -15,
- 3.529
- ],
- [
- 0,
- -3.529
- ],
- [
- 15,
- 3.529
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541000007181,
- 0.705999995213,
- 0.972999961703,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 22.5,
- 18.088
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 4",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 4,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- -3.53,
- 0
- ],
- [
- -2.859,
- -1.429
- ]
- ],
- "o": [
- [
- 2.859,
- -1.429
- ],
- [
- 3.529,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- -9.706,
- 1.12
- ],
- [
- 0,
- -1.12
- ],
- [
- 9.706,
- 1.12
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541000007181,
- 0.705999995213,
- 0.972999961703,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 22.5,
- 8.621
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 5",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 5,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "tm",
- "s": {
- "a": 1,
- "k": [
- {
- "i": {
- "x": [
- 0
- ],
- "y": [
- 1
- ]
- },
- "o": {
- "x": [
- 0.333
- ],
- "y": [
- 0
- ]
- },
- "t": 232,
- "s": [
- 100
- ]
- },
- {
- "t": 245,
- "s": [
- 0
- ]
- }
- ],
- "ix": 1
- },
- "e": {
- "a": 0,
- "k": 100,
- "ix": 2
- },
- "o": {
- "a": 0,
- "k": 0,
- "ix": 3
- },
- "m": 1,
- "ix": 6,
- "nm": "Trim Paths 1",
- "mn": "ADBE Vector Filter - Trim",
- "hd": false
- }
- ],
- "ip": 218,
- "op": 278,
- "st": 30,
- "bm": 0
- },
- {
- "ddd": 0,
- "ind": 6,
- "ty": 4,
- "nm": "fingerprint motion 3",
- "parent": 10,
- "sr": 1,
- "ks": {
- "o": {
- "a": 0,
- "k": 100,
- "ix": 11
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 10
- },
- "p": {
- "a": 0,
- "k": [
- -10.467,
- 814.892,
- 0
- ],
- "ix": 2,
- "l": 2
- },
- "a": {
- "a": 0,
- "k": [
- 22.5,
- 28.676,
- 0
- ],
- "ix": 1,
- "l": 2
- },
- "s": {
- "a": 0,
- "k": [
- 353.53,
- 353.53,
- 100
- ],
- "ix": 6,
- "l": 2
- }
- },
- "ao": 0,
- "shapes": [
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- 3.564,
- 0
- ],
- [
- 2.241,
- 1.694
- ]
- ],
- "o": [
- [
- -2.329,
- 2.012
- ],
- [
- -3.23,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- 8.7,
- -1.624
- ],
- [
- -0.335,
- 1.624
- ],
- [
- -8.7,
- -1.076
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541000007181,
- 0.705999995213,
- 0.972999961703,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 22.837,
- 48.229
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 1",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 1,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- -7.553,
- 0
- ],
- [
- 0,
- -6.83
- ]
- ],
- "o": [
- [
- -0.988,
- -2.577
- ],
- [
- 0,
- -6.83
- ],
- [
- 7.553,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- -12.247,
- 8.824
- ],
- [
- -13.235,
- 3.529
- ],
- [
- 0,
- -8.824
- ],
- [
- 13.235,
- 3.529
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541000007181,
- 0.705999995213,
- 0.972999961703,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 22.5,
- 30.441
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 2",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 2,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- 2.647,
- 0
- ],
- [
- 0.388,
- 2.294
- ],
- [
- 0,
- 0
- ],
- [
- 2.117,
- 0
- ],
- [
- -5.241,
- -1.482
- ]
- ],
- "o": [
- [
- 0,
- 0
- ],
- [
- 0,
- 2.629
- ],
- [
- -2.33,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- -0.353,
- -2.1
- ],
- [
- -7.624,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- 10.95,
- -1.756
- ],
- [
- 10.95,
- -1.244
- ],
- [
- 6.168,
- 3.538
- ],
- [
- 1.456,
- -0.45
- ],
- [
- 0.962,
- -3.415
- ],
- [
- -3.326,
- -7.05
- ],
- [
- -2.568,
- 7.05
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541000007181,
- 0.705999995213,
- 0.972999961703,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 24.786,
- 35.727
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 3",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 3,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- -6.618,
- 0
- ],
- [
- -2.665,
- -4.165
- ]
- ],
- "o": [
- [
- 2.665,
- -4.165
- ],
- [
- 6.618,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- -15,
- 3.529
- ],
- [
- 0,
- -3.529
- ],
- [
- 15,
- 3.529
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541000007181,
- 0.705999995213,
- 0.972999961703,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 22.5,
- 18.088
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 4",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 4,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- -3.53,
- 0
- ],
- [
- -2.859,
- -1.429
- ]
- ],
- "o": [
- [
- 2.859,
- -1.429
- ],
- [
- 3.529,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- -9.706,
- 1.12
- ],
- [
- 0,
- -1.12
- ],
- [
- 9.706,
- 1.12
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541000007181,
- 0.705999995213,
- 0.972999961703,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 22.5,
- 8.621
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 5",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 5,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "tm",
- "s": {
- "a": 0,
- "k": 0,
- "ix": 1
- },
- "e": {
- "a": 1,
- "k": [
- {
- "i": {
- "x": [
- 0.667
- ],
- "y": [
- 1
- ]
- },
- "o": {
- "x": [
- 0.333
- ],
- "y": [
- 0
- ]
- },
- "t": 185,
- "s": [
- 100
- ]
- },
- {
- "t": 199,
- "s": [
- 0
- ]
- }
- ],
- "ix": 2
- },
- "o": {
- "a": 0,
- "k": 0,
- "ix": 3
- },
- "m": 1,
- "ix": 6,
- "nm": "Trim Paths 1",
- "mn": "ADBE Vector Filter - Trim",
- "hd": false
- }
- ],
- "ip": 160,
- "op": 218,
- "st": 30,
- "bm": 0
- },
- {
- "ddd": 0,
- "ind": 7,
- "ty": 4,
- "nm": "fingerprint motion 2",
- "parent": 10,
- "sr": 1,
- "ks": {
- "o": {
- "a": 0,
- "k": 100,
- "ix": 11
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 10
- },
- "p": {
- "a": 0,
- "k": [
- -10.467,
- 814.892,
- 0
- ],
- "ix": 2,
- "l": 2
- },
- "a": {
- "a": 0,
- "k": [
- 22.5,
- 28.676,
- 0
- ],
- "ix": 1,
- "l": 2
- },
- "s": {
- "a": 0,
- "k": [
- 353.53,
- 353.53,
- 100
- ],
- "ix": 6,
- "l": 2
- }
- },
- "ao": 0,
- "shapes": [
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- 3.564,
- 0
- ],
- [
- 2.241,
- 1.694
- ]
- ],
- "o": [
- [
- -2.329,
- 2.012
- ],
- [
- -3.23,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- 8.7,
- -1.624
- ],
- [
- -0.335,
- 1.624
- ],
- [
- -8.7,
- -1.076
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541000007181,
- 0.705999995213,
- 0.972999961703,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 22.837,
- 48.229
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 1",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 1,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- -7.553,
- 0
- ],
- [
- 0,
- -6.83
- ]
- ],
- "o": [
- [
- -0.988,
- -2.577
- ],
- [
- 0,
- -6.83
- ],
- [
- 7.553,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- -12.247,
- 8.824
- ],
- [
- -13.235,
- 3.529
- ],
- [
- 0,
- -8.824
- ],
- [
- 13.235,
- 3.529
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541000007181,
- 0.705999995213,
- 0.972999961703,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 22.5,
- 30.441
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 2",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 2,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- 2.647,
- 0
- ],
- [
- 0.388,
- 2.294
- ],
- [
- 0,
- 0
- ],
- [
- 2.117,
- 0
- ],
- [
- -5.241,
- -1.482
- ]
- ],
- "o": [
- [
- 0,
- 0
- ],
- [
- 0,
- 2.629
- ],
- [
- -2.33,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- -0.353,
- -2.1
- ],
- [
- -7.624,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- 10.95,
- -1.756
- ],
- [
- 10.95,
- -1.244
- ],
- [
- 6.168,
- 3.538
- ],
- [
- 1.456,
- -0.45
- ],
- [
- 0.962,
- -3.415
- ],
- [
- -3.326,
- -7.05
- ],
- [
- -2.568,
- 7.05
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541000007181,
- 0.705999995213,
- 0.972999961703,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 24.786,
- 35.727
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 3",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 3,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- -6.618,
- 0
- ],
- [
- -2.665,
- -4.165
- ]
- ],
- "o": [
- [
- 2.665,
- -4.165
- ],
- [
- 6.618,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- -15,
- 3.529
- ],
- [
- 0,
- -3.529
- ],
- [
- 15,
- 3.529
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541000007181,
- 0.705999995213,
- 0.972999961703,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 22.5,
- 18.088
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 4",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 4,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- -3.53,
- 0
- ],
- [
- -2.859,
- -1.429
- ]
- ],
- "o": [
- [
- 2.859,
- -1.429
- ],
- [
- 3.529,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- -9.706,
- 1.12
- ],
- [
- 0,
- -1.12
- ],
- [
- 9.706,
- 1.12
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541000007181,
- 0.705999995213,
- 0.972999961703,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 22.5,
- 8.621
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 5",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 5,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "tm",
- "s": {
- "a": 1,
- "k": [
- {
- "i": {
- "x": [
- 0
- ],
- "y": [
- 1
- ]
- },
- "o": {
- "x": [
- 0.333
- ],
- "y": [
- 0
- ]
- },
- "t": 138,
- "s": [
- 100
- ]
- },
- {
- "t": 149,
- "s": [
- 0
- ]
- }
- ],
- "ix": 1
- },
- "e": {
- "a": 0,
- "k": 100,
- "ix": 2
- },
- "o": {
- "a": 0,
- "k": 0,
- "ix": 3
- },
- "m": 1,
- "ix": 6,
- "nm": "Trim Paths 1",
- "mn": "ADBE Vector Filter - Trim",
- "hd": false
- }
- ],
- "ip": 0,
- "op": 160,
- "st": 30,
- "bm": 0
- },
- {
- "ddd": 0,
- "ind": 8,
- "ty": 4,
- "nm": "fingerprint motion",
- "parent": 10,
- "sr": 1,
- "ks": {
- "o": {
- "a": 0,
- "k": 100,
- "ix": 11
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 10
- },
- "p": {
- "a": 0,
- "k": [
- -10.467,
- 814.892,
- 0
- ],
- "ix": 2,
- "l": 2
- },
- "a": {
- "a": 0,
- "k": [
- 22.5,
- 28.676,
- 0
- ],
- "ix": 1,
- "l": 2
- },
- "s": {
- "a": 0,
- "k": [
- 353.53,
- 353.53,
- 100
- ],
- "ix": 6,
- "l": 2
- }
- },
- "ao": 0,
- "shapes": [
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- 3.564,
- 0
- ],
- [
- 2.241,
- 1.694
- ]
- ],
- "o": [
- [
- -2.329,
- 2.012
- ],
- [
- -3.23,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- 8.7,
- -1.624
- ],
- [
- -0.335,
- 1.624
- ],
- [
- -8.7,
- -1.076
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541000007181,
- 0.705999995213,
- 0.972999961703,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 22.837,
- 48.229
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 1",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 1,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- -7.553,
- 0
- ],
- [
- 0,
- -6.83
- ]
- ],
- "o": [
- [
- -0.988,
- -2.577
- ],
- [
- 0,
- -6.83
- ],
- [
- 7.553,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- -12.247,
- 8.824
- ],
- [
- -13.235,
- 3.529
- ],
- [
- 0,
- -8.824
- ],
- [
- 13.235,
- 3.529
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541000007181,
- 0.705999995213,
- 0.972999961703,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 22.5,
- 30.441
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 2",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 2,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- 2.647,
- 0
- ],
- [
- 0.388,
- 2.294
- ],
- [
- 0,
- 0
- ],
- [
- 2.117,
- 0
- ],
- [
- -5.241,
- -1.482
- ]
- ],
- "o": [
- [
- 0,
- 0
- ],
- [
- 0,
- 2.629
- ],
- [
- -2.33,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- -0.353,
- -2.1
- ],
- [
- -7.624,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- 10.95,
- -1.756
- ],
- [
- 10.95,
- -1.244
- ],
- [
- 6.168,
- 3.538
- ],
- [
- 1.456,
- -0.45
- ],
- [
- 0.962,
- -3.415
- ],
- [
- -3.326,
- -7.05
- ],
- [
- -2.568,
- 7.05
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541000007181,
- 0.705999995213,
- 0.972999961703,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 24.786,
- 35.727
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 3",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 3,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- -6.618,
- 0
- ],
- [
- -2.665,
- -4.165
- ]
- ],
- "o": [
- [
- 2.665,
- -4.165
- ],
- [
- 6.618,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- -15,
- 3.529
- ],
- [
- 0,
- -3.529
- ],
- [
- 15,
- 3.529
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541000007181,
- 0.705999995213,
- 0.972999961703,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 22.5,
- 18.088
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 4",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 4,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- -3.53,
- 0
- ],
- [
- -2.859,
- -1.429
- ]
- ],
- "o": [
- [
- 2.859,
- -1.429
- ],
- [
- 3.529,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- -9.706,
- 1.12
- ],
- [
- 0,
- -1.12
- ],
- [
- 9.706,
- 1.12
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541000007181,
- 0.705999995213,
- 0.972999961703,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 22.5,
- 8.621
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 5",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 5,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "tm",
- "s": {
- "a": 0,
- "k": 0,
- "ix": 1
- },
- "e": {
- "a": 1,
- "k": [
- {
- "i": {
- "x": [
- 0.667
- ],
- "y": [
- 1
- ]
- },
- "o": {
- "x": [
- 0.333
- ],
- "y": [
- 0
- ]
- },
- "t": 92,
- "s": [
- 100
- ]
- },
- {
- "t": 106,
- "s": [
- 0
- ]
- }
- ],
- "ix": 2
- },
- "o": {
- "a": 0,
- "k": 0,
- "ix": 3
- },
- "m": 1,
- "ix": 6,
- "nm": "Trim Paths 1",
- "mn": "ADBE Vector Filter - Trim",
- "hd": false
- }
- ],
- "ip": 0,
- "op": 160,
- "st": 30,
- "bm": 0
- },
- {
- "ddd": 0,
- "ind": 9,
- "ty": 4,
- "nm": "fingerprint static",
- "parent": 10,
- "sr": 1,
- "ks": {
- "o": {
- "a": 0,
- "k": 100,
- "ix": 11
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 10
- },
- "p": {
- "a": 0,
- "k": [
- -10.467,
- 814.892,
- 0
- ],
- "ix": 2,
- "l": 2
- },
- "a": {
- "a": 0,
- "k": [
- 22.5,
- 28.676,
- 0
- ],
- "ix": 1,
- "l": 2
- },
- "s": {
- "a": 0,
- "k": [
- 353.53,
- 353.53,
- 100
- ],
- "ix": 6,
- "l": 2
- }
- },
- "ao": 0,
- "shapes": [
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- 3.564,
- 0
- ],
- [
- 2.241,
- 1.694
- ]
- ],
- "o": [
- [
- -2.329,
- 2.012
- ],
- [
- -3.23,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- 8.7,
- -1.624
- ],
- [
- -0.335,
- 1.624
- ],
- [
- -8.7,
- -1.076
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.290196078431,
- 0.313725490196,
- 0.352941176471,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 22.837,
- 48.229
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 1",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 1,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- -7.553,
- 0
- ],
- [
- 0,
- -6.83
- ]
- ],
- "o": [
- [
- -0.988,
- -2.577
- ],
- [
- 0,
- -6.83
- ],
- [
- 7.553,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- -12.247,
- 8.824
- ],
- [
- -13.235,
- 3.529
- ],
- [
- 0,
- -8.824
- ],
- [
- 13.235,
- 3.529
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.290196078431,
- 0.313725490196,
- 0.352941176471,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 22.5,
- 30.441
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 2",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 2,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- 2.647,
- 0
- ],
- [
- 0.388,
- 2.294
- ],
- [
- 0,
- 0
- ],
- [
- 2.117,
- 0
- ],
- [
- -5.241,
- -1.482
- ]
- ],
- "o": [
- [
- 0,
- 0
- ],
- [
- 0,
- 2.629
- ],
- [
- -2.33,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- -0.353,
- -2.1
- ],
- [
- -7.624,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- 10.95,
- -1.756
- ],
- [
- 10.95,
- -1.244
- ],
- [
- 6.168,
- 3.538
- ],
- [
- 1.456,
- -0.45
- ],
- [
- 0.962,
- -3.415
- ],
- [
- -3.326,
- -7.05
- ],
- [
- -2.568,
- 7.05
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.290196078431,
- 0.313725490196,
- 0.352941176471,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 24.786,
- 35.727
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 3",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 3,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- -6.618,
- 0
- ],
- [
- -2.665,
- -4.165
- ]
- ],
- "o": [
- [
- 2.665,
- -4.165
- ],
- [
- 6.618,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- -15,
- 3.529
- ],
- [
- 0,
- -3.529
- ],
- [
- 15,
- 3.529
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.290196078431,
- 0.313725490196,
- 0.352941176471,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 22.5,
- 18.088
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 4",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 4,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- -3.53,
- 0
- ],
- [
- -2.859,
- -1.429
- ]
- ],
- "o": [
- [
- 2.859,
- -1.429
- ],
- [
- 3.529,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- -9.706,
- 1.12
- ],
- [
- 0,
- -1.12
- ],
- [
- 9.706,
- 1.12
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.290196078431,
- 0.313725490196,
- 0.352941176471,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 3,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 22.5,
- 8.621
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 5",
- "np": 2,
- "cix": 2,
- "bm": 0,
- "ix": 5,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "tm",
- "s": {
- "a": 0,
- "k": 0,
- "ix": 1
- },
- "e": {
- "a": 0,
- "k": 100,
- "ix": 2
- },
- "o": {
- "a": 0,
- "k": 0,
- "ix": 3
- },
- "m": 1,
- "ix": 6,
- "nm": "Trim Paths 1",
- "mn": "ADBE Vector Filter - Trim",
- "hd": false
- }
- ],
- "ip": 0,
- "op": 630,
- "st": 30,
- "bm": 0
- },
- {
- "ddd": 0,
- "ind": 10,
- "ty": 4,
- "nm": "background",
- "sr": 1,
- "ks": {
- "o": {
- "a": 0,
- "k": 100,
- "ix": 11
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 10
- },
- "p": {
- "a": 0,
- "k": [
- 151.14,
- 205.871,
- 0
- ],
- "ix": 2,
- "l": 2
- },
- "a": {
- "a": 0,
- "k": [
- -11.477,
- 810.793,
- 0
- ],
- "ix": 1,
- "l": 2
- },
- "s": {
- "a": 1,
- "k": [
- {
- "i": {
- "x": [
- 0.511,
- 0.511,
- 0.667
- ],
- "y": [
- 1,
- 1,
- 1
- ]
- },
- "o": {
- "x": [
- 0.333,
- 0.333,
- 0.333
- ],
- "y": [
- 0,
- 0,
- 0
- ]
- },
- "t": 92,
- "s": [
- 17.82,
- 17.82,
- 100
- ]
- },
- {
- "i": {
- "x": [
- 0.833,
- 0.833,
- 0.833
- ],
- "y": [
- 1,
- 1,
- 1
- ]
- },
- "o": {
- "x": [
- 0.333,
- 0.333,
- 0.333
- ],
- "y": [
- 0,
- 0,
- 0
- ]
- },
- "t": 102,
- "s": [
- 16.92,
- 16.92,
- 100
- ]
- },
- {
- "i": {
- "x": [
- 0.369,
- 0.369,
- 0.667
- ],
- "y": [
- 1,
- 1,
- 1
- ]
- },
- "o": {
- "x": [
- 0.292,
- 0.292,
- 0.167
- ],
- "y": [
- 0,
- 0,
- 0
- ]
- },
- "t": 138,
- "s": [
- 16.92,
- 16.92,
- 100
- ]
- },
- {
- "i": {
- "x": [
- 0.667,
- 0.667,
- 0.667
- ],
- "y": [
- 1,
- 1,
- 1
- ]
- },
- "o": {
- "x": [
- 0.167,
- 0.167,
- 0.167
- ],
- "y": [
- 0,
- 0,
- 0
- ]
- },
- "t": 148,
- "s": [
- 17.82,
- 17.82,
- 100
- ]
- },
- {
- "i": {
- "x": [
- 0.511,
- 0.511,
- 0.667
- ],
- "y": [
- 1,
- 1,
- 1
- ]
- },
- "o": {
- "x": [
- 0.333,
- 0.333,
- 0.333
- ],
- "y": [
- 0,
- 0,
- 0
- ]
- },
- "t": 185,
- "s": [
- 17.82,
- 17.82,
- 100
- ]
- },
- {
- "i": {
- "x": [
- 0.833,
- 0.833,
- 0.833
- ],
- "y": [
- 1,
- 1,
- 1
- ]
- },
- "o": {
- "x": [
- 0.333,
- 0.333,
- 0.333
- ],
- "y": [
- 0,
- 0,
- 0
- ]
- },
- "t": 195,
- "s": [
- 16.92,
- 16.92,
- 100
- ]
- },
- {
- "i": {
- "x": [
- 0.369,
- 0.369,
- 0.667
- ],
- "y": [
- 1,
- 1,
- 1
- ]
- },
- "o": {
- "x": [
- 0.292,
- 0.292,
- 0.167
- ],
- "y": [
- 0,
- 0,
- 0
- ]
- },
- "t": 232,
- "s": [
- 16.92,
- 16.92,
- 100
- ]
- },
- {
- "i": {
- "x": [
- 0.667,
- 0.667,
- 0.667
- ],
- "y": [
- 1,
- 1,
- 1
- ]
- },
- "o": {
- "x": [
- 0.167,
- 0.167,
- 0.167
- ],
- "y": [
- 0,
- 0,
- 0
- ]
- },
- "t": 242,
- "s": [
- 17.82,
- 17.82,
- 100
- ]
- },
- {
- "i": {
- "x": [
- 0.511,
- 0.511,
- 0.667
- ],
- "y": [
- 1,
- 1,
- 1
- ]
- },
- "o": {
- "x": [
- 0.333,
- 0.333,
- 0.333
- ],
- "y": [
- 0,
- 0,
- 0
- ]
- },
- "t": 285,
- "s": [
- 17.82,
- 17.82,
- 100
- ]
- },
- {
- "i": {
- "x": [
- 0.833,
- 0.833,
- 0.833
- ],
- "y": [
- 1,
- 1,
- 1
- ]
- },
- "o": {
- "x": [
- 0.333,
- 0.333,
- 0.333
- ],
- "y": [
- 0,
- 0,
- 0
- ]
- },
- "t": 295,
- "s": [
- 16.92,
- 16.92,
- 100
- ]
- },
- {
- "i": {
- "x": [
- 0.369,
- 0.369,
- 0.667
- ],
- "y": [
- 1,
- 1,
- 1
- ]
- },
- "o": {
- "x": [
- 0.292,
- 0.292,
- 0.167
- ],
- "y": [
- 0,
- 0,
- 0
- ]
- },
- "t": 335,
- "s": [
- 16.92,
- 16.92,
- 100
- ]
- },
- {
- "i": {
- "x": [
- 0.667,
- 0.667,
- 0.667
- ],
- "y": [
- 1,
- 1,
- 1
- ]
- },
- "o": {
- "x": [
- 0.167,
- 0.167,
- 0.167
- ],
- "y": [
- 0,
- 0,
- 0
- ]
- },
- "t": 345,
- "s": [
- 17.82,
- 17.82,
- 100
- ]
- },
- {
- "i": {
- "x": [
- 0.511,
- 0.511,
- 0.667
- ],
- "y": [
- 1,
- 1,
- 1
- ]
- },
- "o": {
- "x": [
- 0.333,
- 0.333,
- 0.333
- ],
- "y": [
- 0,
- 0,
- 0
- ]
- },
- "t": 380,
- "s": [
- 17.82,
- 17.82,
- 100
- ]
- },
- {
- "i": {
- "x": [
- 0.833,
- 0.833,
- 0.833
- ],
- "y": [
- 1,
- 1,
- 1
- ]
- },
- "o": {
- "x": [
- 0.333,
- 0.333,
- 0.333
- ],
- "y": [
- 0,
- 0,
- 0
- ]
- },
- "t": 390,
- "s": [
- 16.92,
- 16.92,
- 100
- ]
- },
- {
- "i": {
- "x": [
- 0.369,
- 0.369,
- 0.667
- ],
- "y": [
- 1,
- 1,
- 1
- ]
- },
- "o": {
- "x": [
- 0.292,
- 0.292,
- 0.167
- ],
- "y": [
- 0,
- 0,
- 0
- ]
- },
- "t": 429,
- "s": [
- 16.92,
- 16.92,
- 100
- ]
- },
- {
- "t": 439,
- "s": [
- 17.82,
- 17.82,
- 100
- ]
- }
- ],
- "ix": 6,
- "l": 2
- }
- },
- "ao": 0,
- "shapes": [
- {
- "ty": "gr",
- "it": [
- {
- "d": 1,
- "ty": "el",
- "s": {
- "a": 0,
- "k": [
- 258.387,
- 258.387
- ],
- "ix": 2
- },
- "p": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 3
- },
- "nm": "Ellipse Path 1",
- "mn": "ADBE Vector Shape - Ellipse",
- "hd": false
- },
- {
- "ty": "fl",
- "c": {
- "a": 1,
- "k": [
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 0.833
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0.167
- ]
- },
- "t": 92,
- "s": [
- 0.247058838489,
- 0.305882352941,
- 0.396078461292,
- 1
- ]
- },
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 0.833
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0.167
- ]
- },
- "t": 98,
- "s": [
- 0.105882360421,
- 0.152941176471,
- 0.223529426724,
- 1
- ]
- },
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 0.833
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0.167
- ]
- },
- "t": 138,
- "s": [
- 0.105882360421,
- 0.152941176471,
- 0.223529426724,
- 1
- ]
- },
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 0.833
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0.167
- ]
- },
- "t": 143,
- "s": [
- 0.247058838489,
- 0.305882352941,
- 0.396078461292,
- 1
- ]
- },
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 0.833
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0.167
- ]
- },
- "t": 185,
- "s": [
- 0.247058838489,
- 0.305882352941,
- 0.396078461292,
- 1
- ]
- },
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 0.833
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0.167
- ]
- },
- "t": 190,
- "s": [
- 0.117647059262,
- 0.152941182256,
- 0.219607844949,
- 1
- ]
- },
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 0.833
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0.167
- ]
- },
- "t": 232,
- "s": [
- 0.117647059262,
- 0.152941182256,
- 0.219607844949,
- 1
- ]
- },
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 0.833
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0.167
- ]
- },
- "t": 237,
- "s": [
- 0.258823543787,
- 0.305882364511,
- 0.388235300779,
- 1
- ]
- },
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 0.833
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0.167
- ]
- },
- "t": 285,
- "s": [
- 0.258823543787,
- 0.305882364511,
- 0.388235300779,
- 1
- ]
- },
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 0.833
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0.167
- ]
- },
- "t": 290,
- "s": [
- 0.117647059262,
- 0.152941182256,
- 0.219607844949,
- 1
- ]
- },
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 0.833
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0.167
- ]
- },
- "t": 335,
- "s": [
- 0.117647059262,
- 0.152941182256,
- 0.219607844949,
- 1
- ]
- },
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 0.833
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0.167
- ]
- },
- "t": 340,
- "s": [
- 0.258823543787,
- 0.305882364511,
- 0.388235300779,
- 1
- ]
- },
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 0.833
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0.167
- ]
- },
- "t": 380,
- "s": [
- 0.258823543787,
- 0.305882364511,
- 0.388235300779,
- 1
- ]
- },
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 0.833
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0.167
- ]
- },
- "t": 385,
- "s": [
- 0.117647059262,
- 0.152941182256,
- 0.219607844949,
- 1
- ]
- },
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 0.833
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0.167
- ]
- },
- "t": 429,
- "s": [
- 0.117647059262,
- 0.152941182256,
- 0.219607844949,
- 1
- ]
- },
- {
- "t": 434,
- "s": [
- 0.258823543787,
- 0.305882364511,
- 0.388235300779,
- 1
- ]
- }
- ],
- "ix": 4
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 5
- },
- "r": 1,
- "bm": 0,
- "nm": "Fill 1",
- "mn": "ADBE Vector Graphic - Fill",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- -8.807,
- 813.193
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Ellipse 1",
- "np": 3,
- "cix": 2,
- "bm": 0,
- "ix": 1,
- "mn": "ADBE Vector Group",
- "hd": false
- }
- ],
- "ip": 0,
- "op": 630,
- "st": 30,
- "bm": 0
- },
- {
- "ddd": 0,
- "ind": 11,
- "ty": 4,
- "nm": "Phone/Phone_Illustration Outlines 2",
- "sr": 1,
- "ks": {
- "o": {
- "a": 0,
- "k": 100,
- "ix": 11
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 10
- },
- "p": {
- "a": 0,
- "k": [
- 151.5,
- 139.97,
- 0
- ],
- "ix": 2,
- "l": 2
- },
- "a": {
- "a": 0,
- "k": [
- 64,
- 118.5,
- 0
- ],
- "ix": 1,
- "l": 2
- },
- "s": {
- "a": 0,
- "k": [
- 103.629,
- 103.629,
- 100
- ],
- "ix": 6,
- "l": 2
- }
- },
- "ao": 0,
- "shapes": [
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- 4.901,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- 0,
- 4.902
- ],
- [
- 0,
- 0
- ],
- [
- -4.902,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- 0,
- -4.902
- ]
- ],
- "o": [
- [
- 0,
- 4.902
- ],
- [
- 0,
- 0
- ],
- [
- -4.902,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- 0,
- -4.902
- ],
- [
- 0,
- 0
- ],
- [
- 4.901,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- 58.897,
- 106.681
- ],
- [
- 50.008,
- 115.572
- ],
- [
- -52.229,
- 115.572
- ],
- [
- -61.118,
- 106.681
- ],
- [
- -61.118,
- -106.68
- ],
- [
- -52.229,
- -115.571
- ],
- [
- 50.008,
- -115.571
- ],
- [
- 58.897,
- -106.68
- ]
- ],
- "c": true
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ind": 1,
- "ty": "sh",
- "ix": 2,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 1.227
- ],
- [
- 0,
- 0
- ],
- [
- 1.227,
- 0.001
- ],
- [
- 0,
- 0
- ],
- [
- 6.127,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- 0,
- -6.128
- ],
- [
- 0,
- 0
- ],
- [
- -6.127,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- 0,
- 6.128
- ],
- [
- 0,
- 0
- ],
- [
- 0,
- 1.228
- ],
- [
- 0,
- 0
- ],
- [
- 1.227,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "o": [
- [
- 0,
- 0
- ],
- [
- 0,
- -1.228
- ],
- [
- 0,
- 0
- ],
- [
- 0,
- -6.128
- ],
- [
- 0,
- 0
- ],
- [
- -6.127,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- 0,
- 6.128
- ],
- [
- 0,
- 0
- ],
- [
- 6.127,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- 1.227,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- 0,
- -1.227
- ],
- [
- 0,
- 0
- ],
- [
- 1.227,
- 0
- ]
- ],
- "v": [
- [
- 63.341,
- -48.896
- ],
- [
- 63.341,
- -57.786
- ],
- [
- 61.12,
- -60.008
- ],
- [
- 61.12,
- -106.68
- ],
- [
- 50.008,
- -117.795
- ],
- [
- -52.229,
- -117.795
- ],
- [
- -63.341,
- -106.68
- ],
- [
- -63.341,
- 106.681
- ],
- [
- -52.229,
- 117.795
- ],
- [
- 50.008,
- 117.795
- ],
- [
- 61.12,
- 106.681
- ],
- [
- 61.12,
- -2.223
- ],
- [
- 63.341,
- -4.445
- ],
- [
- 63.341,
- -26.671
- ],
- [
- 61.12,
- -28.893
- ],
- [
- 61.12,
- -46.674
- ]
- ],
- "c": true
- },
- "ix": 2
- },
- "nm": "Path 2",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "mm",
- "mm": 1,
- "nm": "Merge Paths 1",
- "mn": "ADBE Vector Filter - Merge",
- "hd": false
- },
- {
- "ty": "fl",
- "c": {
- "a": 0,
- "k": [
- 0.501999978458,
- 0.525,
- 0.545000023935,
- 1
- ],
- "ix": 4
- },
- "o": {
- "a": 1,
- "k": [
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 0.833
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0.167
- ]
- },
- "t": 60,
- "s": [
- 100
- ]
- },
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 0.833
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0.167
- ]
- },
- "t": 70,
- "s": [
- 0
- ]
- },
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 0.833
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0.167
- ]
- },
- "t": 489,
- "s": [
- 0
- ]
- },
- {
- "t": 499,
- "s": [
- 100
- ]
- }
- ],
- "ix": 5
- },
- "r": 1,
- "bm": 0,
- "nm": "Fill 1",
- "mn": "ADBE Vector Graphic - Fill",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 63.591,
- 118.045
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 1",
- "np": 4,
- "cix": 2,
- "bm": 0,
- "ix": 1,
- "mn": "ADBE Vector Group",
- "hd": false
- }
- ],
- "ip": 0,
- "op": 630,
- "st": 30,
- "bm": 0
- },
- {
- "ddd": 0,
- "ind": 13,
- "ty": 4,
- "nm": "checkmark 2",
- "parent": 14,
- "sr": 1,
- "ks": {
- "o": {
- "a": 0,
- "k": 100,
- "ix": 11
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 10
- },
- "p": {
- "a": 0,
- "k": [
- 338.091,
- 629.95,
- 0
- ],
- "ix": 2,
- "l": 2
- },
- "a": {
- "a": 0,
- "k": [
- 334.381,
- 630.336,
- 0
- ],
- "ix": 1,
- "l": 2
- },
- "s": {
- "a": 0,
- "k": [
- 104.745,
- 104.745,
- 100
- ],
- "ix": 6,
- "l": 2
- }
- },
- "ao": 0,
- "shapes": [
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "o": [
- [
- 0,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- 283,
- 629.5
- ],
- [
- 322.5,
- 661.5
- ],
- [
- 382.5,
- 591.5
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.400000029919,
- 0.61568627451,
- 0.964705942191,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 1,
- "k": [
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 0.833
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0.167
- ]
- },
- "t": 487,
- "s": [
- 100
- ]
- },
- {
- "t": 490,
- "s": [
- 0
- ]
- }
- ],
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 14,
- "ix": 5
- },
- "lc": 1,
- "lj": 1,
- "ml": 4,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Shape 1",
- "np": 3,
- "cix": 2,
- "bm": 0,
- "ix": 1,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "tm",
- "s": {
- "a": 0,
- "k": 0,
- "ix": 1
- },
- "e": {
- "a": 1,
- "k": [
- {
- "i": {
- "x": [
- 0
- ],
- "y": [
- 1
- ]
- },
- "o": {
- "x": [
- 0.645
- ],
- "y": [
- 0
- ]
- },
- "t": 433,
- "s": [
- 0
- ]
- },
- {
- "t": 447,
- "s": [
- 100
- ]
- }
- ],
- "ix": 2
- },
- "o": {
- "a": 0,
- "k": 0,
- "ix": 3
- },
- "m": 1,
- "ix": 2,
- "nm": "Trim Paths 1",
- "mn": "ADBE Vector Filter - Trim",
- "hd": false
- }
- ],
- "ip": 429,
- "op": 630,
- "st": 30,
- "bm": 0
- },
- {
- "ddd": 0,
- "ind": 14,
- "ty": 4,
- "nm": "checkmark",
- "sr": 1,
- "ks": {
- "o": {
- "a": 0,
- "k": 100,
- "ix": 11
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 10
- },
- "p": {
- "a": 0,
- "k": [
- 200.737,
- 254.567,
- 0
- ],
- "ix": 2,
- "l": 2
- },
- "a": {
- "a": 0,
- "k": [
- 338.647,
- 629.648,
- 0
- ],
- "ix": 1,
- "l": 2
- },
- "s": {
- "a": 1,
- "k": [
- {
- "i": {
- "x": [
- 0.549,
- 0.549,
- 0.667
- ],
- "y": [
- 1,
- 1,
- 1
- ]
- },
- "o": {
- "x": [
- 0.04,
- 0.04,
- 0.333
- ],
- "y": [
- 0,
- 0,
- 0
- ]
- },
- "t": 429,
- "s": [
- 7.2,
- 7.2,
- 100
- ]
- },
- {
- "i": {
- "x": [
- 0.323,
- 0.323,
- 0.667
- ],
- "y": [
- 1,
- 1,
- 1
- ]
- },
- "o": {
- "x": [
- 0.271,
- 0.271,
- 0.333
- ],
- "y": [
- 0,
- 0,
- 0
- ]
- },
- "t": 437,
- "s": [
- 19.525,
- 19.525,
- 100
- ]
- },
- {
- "i": {
- "x": [
- 0.833,
- 0.833,
- 0.833
- ],
- "y": [
- 1,
- 1,
- 1
- ]
- },
- "o": {
- "x": [
- 0.167,
- 0.167,
- 0.167
- ],
- "y": [
- 0,
- 0,
- 0
- ]
- },
- "t": 454,
- "s": [
- 17.185,
- 17.185,
- 100
- ]
- },
- {
- "i": {
- "x": [
- 0.913,
- 0.913,
- 0.833
- ],
- "y": [
- 1,
- 1,
- 1
- ]
- },
- "o": {
- "x": [
- 1,
- 1,
- 0.167
- ],
- "y": [
- 0,
- 0,
- 0
- ]
- },
- "t": 480,
- "s": [
- 17.185,
- 17.185,
- 100
- ]
- },
- {
- "t": 490,
- "s": [
- 7.2,
- 7.2,
- 100
- ]
- }
- ],
- "ix": 6,
- "l": 2
- }
- },
- "ao": 0,
- "shapes": [
- {
- "ty": "gr",
- "it": [
- {
- "d": 1,
- "ty": "el",
- "s": {
- "a": 0,
- "k": [
- 177.191,
- 177.191
- ],
- "ix": 2
- },
- "p": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 3
- },
- "nm": "Ellipse Path 1",
- "mn": "ADBE Vector Shape - Ellipse",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.400000029919,
- 0.61568627451,
- 0.964705942191,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 1,
- "k": [
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 0.833
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0.167
- ]
- },
- "t": 482,
- "s": [
- 100
- ]
- },
- {
- "t": 490,
- "s": [
- 0
- ]
- }
- ],
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 14,
- "ix": 5
- },
- "lc": 1,
- "lj": 1,
- "ml": 4,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "fl",
- "c": {
- "a": 0,
- "k": [
- 0.125490196078,
- 0.129411764706,
- 0.141176470588,
- 1
- ],
- "ix": 4
- },
- "o": {
- "a": 1,
- "k": [
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 0.833
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0.167
- ]
- },
- "t": 482,
- "s": [
- 100
- ]
- },
- {
- "t": 490,
- "s": [
- 0
- ]
- }
- ],
- "ix": 5
- },
- "r": 1,
- "bm": 0,
- "nm": "Fill 1",
- "mn": "ADBE Vector Graphic - Fill",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 338.104,
- 629.943
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Ellipse 1",
- "np": 3,
- "cix": 2,
- "bm": 0,
- "ix": 1,
- "mn": "ADBE Vector Group",
- "hd": false
- }
- ],
- "ip": 429,
- "op": 630,
- "st": 30,
- "bm": 0
- },
- {
- "ddd": 0,
- "ind": 15,
- "ty": 4,
- "nm": "Shape Layer 20",
- "sr": 1,
- "ks": {
- "o": {
- "a": 0,
- "k": 100,
- "ix": 11
- },
- "r": {
- "a": 0,
- "k": 270,
- "ix": 10
- },
- "p": {
- "a": 0,
- "k": [
- 151.32,
- 206.475,
- 0
- ],
- "ix": 2,
- "l": 2
- },
- "a": {
- "a": 0,
- "k": [
- 37.523,
- 788.471,
- 0
- ],
- "ix": 1,
- "l": 2
- },
- "s": {
- "a": 0,
- "k": [
- 17.09,
- 17.09,
- 100
- ],
- "ix": 6,
- "l": 2
- }
- },
- "ao": 0,
- "shapes": [
- {
- "ty": "gr",
- "it": [
- {
- "d": 1,
- "ty": "el",
- "s": {
- "a": 0,
- "k": [
- 793.047,
- 793.047
- ],
- "ix": 2
- },
- "p": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 3
- },
- "nm": "Ellipse Path 1",
- "mn": "ADBE Vector Shape - Ellipse",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541176470588,
- 0.705882352941,
- 0.972549079446,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 1,
- "k": [
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 0.833
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0.167
- ]
- },
- "t": 480,
- "s": [
- 100
- ]
- },
- {
- "t": 486,
- "s": [
- 0
- ]
- }
- ],
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 34,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 4,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 37.523,
- 787.523
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100.278,
- 100.278
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Ellipse 1",
- "np": 3,
- "cix": 2,
- "bm": 0,
- "ix": 1,
- "mn": "ADBE Vector Group",
- "hd": false
- }
- ],
- "ip": 477,
- "op": 630,
- "st": 30,
- "bm": 0
- },
- {
- "ddd": 0,
- "ind": 16,
- "ty": 4,
- "nm": "Shape Layer 19",
- "sr": 1,
- "ks": {
- "o": {
- "a": 0,
- "k": 100,
- "ix": 11
- },
- "r": {
- "a": 0,
- "k": 270,
- "ix": 10
- },
- "p": {
- "a": 0,
- "k": [
- 151.32,
- 206.475,
- 0
- ],
- "ix": 2,
- "l": 2
- },
- "a": {
- "a": 0,
- "k": [
- 37.523,
- 788.471,
- 0
- ],
- "ix": 1,
- "l": 2
- },
- "s": {
- "a": 0,
- "k": [
- 17.09,
- 17.09,
- 100
- ],
- "ix": 6,
- "l": 2
- }
- },
- "ao": 0,
- "shapes": [
- {
- "ty": "gr",
- "it": [
- {
- "d": 1,
- "ty": "el",
- "s": {
- "a": 0,
- "k": [
- 793.047,
- 793.047
- ],
- "ix": 2
- },
- "p": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 3
- },
- "nm": "Ellipse Path 1",
- "mn": "ADBE Vector Shape - Ellipse",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541176470588,
- 0.705882352941,
- 0.972549079446,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 34,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 4,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 37.523,
- 787.523
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100.278,
- 100.278
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Ellipse 1",
- "np": 3,
- "cix": 2,
- "bm": 0,
- "ix": 1,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "tm",
- "s": {
- "a": 0,
- "k": 0,
- "ix": 1
- },
- "e": {
- "a": 1,
- "k": [
- {
- "i": {
- "x": [
- 0.2
- ],
- "y": [
- 1
- ]
- },
- "o": {
- "x": [
- 0.4
- ],
- "y": [
- 0
- ]
- },
- "t": 380,
- "s": [
- 0
- ]
- },
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 1
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0
- ]
- },
- "t": 429,
- "s": [
- 22.5
- ]
- },
- {
- "t": 440,
- "s": [
- 26
- ]
- }
- ],
- "ix": 2
- },
- "o": {
- "a": 0,
- "k": 365,
- "ix": 3
- },
- "m": 1,
- "ix": 2,
- "nm": "Trim Paths 1",
- "mn": "ADBE Vector Filter - Trim",
- "hd": false
- }
- ],
- "ip": -7,
- "op": 477,
- "st": 30,
- "bm": 0
- },
- {
- "ddd": 0,
- "ind": 17,
- "ty": 4,
- "nm": "Shape Layer 18",
- "sr": 1,
- "ks": {
- "o": {
- "a": 0,
- "k": 100,
- "ix": 11
- },
- "r": {
- "a": 0,
- "k": 270,
- "ix": 10
- },
- "p": {
- "a": 0,
- "k": [
- 151.32,
- 206.475,
- 0
- ],
- "ix": 2,
- "l": 2
- },
- "a": {
- "a": 0,
- "k": [
- 37.523,
- 788.471,
- 0
- ],
- "ix": 1,
- "l": 2
- },
- "s": {
- "a": 0,
- "k": [
- 17.09,
- 17.09,
- 100
- ],
- "ix": 6,
- "l": 2
- }
- },
- "ao": 0,
- "shapes": [
- {
- "ty": "gr",
- "it": [
- {
- "d": 1,
- "ty": "el",
- "s": {
- "a": 0,
- "k": [
- 793.047,
- 793.047
- ],
- "ix": 2
- },
- "p": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 3
- },
- "nm": "Ellipse Path 1",
- "mn": "ADBE Vector Shape - Ellipse",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.18431372549,
- 0.223529426724,
- 0.282352941176,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 1,
- "k": [
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 0.833
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0.167
- ]
- },
- "t": 69,
- "s": [
- 0
- ]
- },
- {
- "t": 79,
- "s": [
- 100
- ]
- }
- ],
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 34,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 4,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 37.523,
- 787.523
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100.278,
- 100.278
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Ellipse 1",
- "np": 3,
- "cix": 2,
- "bm": 0,
- "ix": 1,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "tm",
- "s": {
- "a": 0,
- "k": 0,
- "ix": 1
- },
- "e": {
- "a": 0,
- "k": 22.5,
- "ix": 2
- },
- "o": {
- "a": 0,
- "k": 365,
- "ix": 3
- },
- "m": 1,
- "ix": 2,
- "nm": "Trim Paths 1",
- "mn": "ADBE Vector Filter - Trim",
- "hd": false
- }
- ],
- "ip": -7,
- "op": 477,
- "st": 30,
- "bm": 0
- },
- {
- "ddd": 0,
- "ind": 18,
- "ty": 4,
- "nm": "Shape Layer 17",
- "sr": 1,
- "ks": {
- "o": {
- "a": 0,
- "k": 100,
- "ix": 11
- },
- "r": {
- "a": 0,
- "k": 180,
- "ix": 10
- },
- "p": {
- "a": 0,
- "k": [
- 151.32,
- 206.475,
- 0
- ],
- "ix": 2,
- "l": 2
- },
- "a": {
- "a": 0,
- "k": [
- 37.523,
- 788.471,
- 0
- ],
- "ix": 1,
- "l": 2
- },
- "s": {
- "a": 0,
- "k": [
- 17.09,
- 17.09,
- 100
- ],
- "ix": 6,
- "l": 2
- }
- },
- "ao": 0,
- "shapes": [
- {
- "ty": "gr",
- "it": [
- {
- "d": 1,
- "ty": "el",
- "s": {
- "a": 0,
- "k": [
- 793.047,
- 793.047
- ],
- "ix": 2
- },
- "p": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 3
- },
- "nm": "Ellipse Path 1",
- "mn": "ADBE Vector Shape - Ellipse",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541176470588,
- 0.705882352941,
- 0.972549079446,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 34,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 4,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 37.523,
- 787.523
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100.278,
- 100.278
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Ellipse 1",
- "np": 3,
- "cix": 2,
- "bm": 0,
- "ix": 1,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "tm",
- "s": {
- "a": 0,
- "k": 0,
- "ix": 1
- },
- "e": {
- "a": 1,
- "k": [
- {
- "i": {
- "x": [
- 0.21
- ],
- "y": [
- 1
- ]
- },
- "o": {
- "x": [
- 0.564
- ],
- "y": [
- 0
- ]
- },
- "t": 285,
- "s": [
- 0
- ]
- },
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 1
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0
- ]
- },
- "t": 335,
- "s": [
- 22.5
- ]
- },
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 1
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0
- ]
- },
- "t": 429,
- "s": [
- 22.5
- ]
- },
- {
- "t": 440,
- "s": [
- 26
- ]
- }
- ],
- "ix": 2
- },
- "o": {
- "a": 0,
- "k": 365,
- "ix": 3
- },
- "m": 1,
- "ix": 2,
- "nm": "Trim Paths 1",
- "mn": "ADBE Vector Filter - Trim",
- "hd": false
- }
- ],
- "ip": -7,
- "op": 477,
- "st": 30,
- "bm": 0
- },
- {
- "ddd": 0,
- "ind": 19,
- "ty": 4,
- "nm": "Shape Layer 16",
- "sr": 1,
- "ks": {
- "o": {
- "a": 0,
- "k": 100,
- "ix": 11
- },
- "r": {
- "a": 0,
- "k": 180,
- "ix": 10
- },
- "p": {
- "a": 0,
- "k": [
- 151.32,
- 206.475,
- 0
- ],
- "ix": 2,
- "l": 2
- },
- "a": {
- "a": 0,
- "k": [
- 37.523,
- 788.471,
- 0
- ],
- "ix": 1,
- "l": 2
- },
- "s": {
- "a": 0,
- "k": [
- 17.09,
- 17.09,
- 100
- ],
- "ix": 6,
- "l": 2
- }
- },
- "ao": 0,
- "shapes": [
- {
- "ty": "gr",
- "it": [
- {
- "d": 1,
- "ty": "el",
- "s": {
- "a": 0,
- "k": [
- 793.047,
- 793.047
- ],
- "ix": 2
- },
- "p": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 3
- },
- "nm": "Ellipse Path 1",
- "mn": "ADBE Vector Shape - Ellipse",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.18431372549,
- 0.223529426724,
- 0.282352941176,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 1,
- "k": [
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 0.833
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0.167
- ]
- },
- "t": 69,
- "s": [
- 0
- ]
- },
- {
- "t": 79,
- "s": [
- 100
- ]
- }
- ],
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 34,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 4,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 37.523,
- 787.523
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100.278,
- 100.278
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Ellipse 1",
- "np": 3,
- "cix": 2,
- "bm": 0,
- "ix": 1,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "tm",
- "s": {
- "a": 0,
- "k": 0,
- "ix": 1
- },
- "e": {
- "a": 0,
- "k": 22.5,
- "ix": 2
- },
- "o": {
- "a": 0,
- "k": 365,
- "ix": 3
- },
- "m": 1,
- "ix": 2,
- "nm": "Trim Paths 1",
- "mn": "ADBE Vector Filter - Trim",
- "hd": false
- }
- ],
- "ip": -7,
- "op": 477,
- "st": 30,
- "bm": 0
- },
- {
- "ddd": 0,
- "ind": 20,
- "ty": 4,
- "nm": "Shape Layer 15",
- "sr": 1,
- "ks": {
- "o": {
- "a": 0,
- "k": 100,
- "ix": 11
- },
- "r": {
- "a": 0,
- "k": 90,
- "ix": 10
- },
- "p": {
- "a": 0,
- "k": [
- 151.32,
- 206.475,
- 0
- ],
- "ix": 2,
- "l": 2
- },
- "a": {
- "a": 0,
- "k": [
- 37.523,
- 788.471,
- 0
- ],
- "ix": 1,
- "l": 2
- },
- "s": {
- "a": 0,
- "k": [
- 17.09,
- 17.09,
- 100
- ],
- "ix": 6,
- "l": 2
- }
- },
- "ao": 0,
- "shapes": [
- {
- "ty": "gr",
- "it": [
- {
- "d": 1,
- "ty": "el",
- "s": {
- "a": 0,
- "k": [
- 793.047,
- 793.047
- ],
- "ix": 2
- },
- "p": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 3
- },
- "nm": "Ellipse Path 1",
- "mn": "ADBE Vector Shape - Ellipse",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541176470588,
- 0.705882352941,
- 0.972549079446,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 34,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 4,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 37.523,
- 787.523
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100.278,
- 100.278
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Ellipse 1",
- "np": 3,
- "cix": 2,
- "bm": 0,
- "ix": 1,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "tm",
- "s": {
- "a": 0,
- "k": 0,
- "ix": 1
- },
- "e": {
- "a": 1,
- "k": [
- {
- "i": {
- "x": [
- 0.2
- ],
- "y": [
- 1
- ]
- },
- "o": {
- "x": [
- 0.4
- ],
- "y": [
- 0
- ]
- },
- "t": 185,
- "s": [
- 0
- ]
- },
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 1
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0
- ]
- },
- "t": 232,
- "s": [
- 22.5
- ]
- },
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 1
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0
- ]
- },
- "t": 429,
- "s": [
- 22.5
- ]
- },
- {
- "t": 440,
- "s": [
- 26
- ]
- }
- ],
- "ix": 2
- },
- "o": {
- "a": 0,
- "k": 365,
- "ix": 3
- },
- "m": 1,
- "ix": 2,
- "nm": "Trim Paths 1",
- "mn": "ADBE Vector Filter - Trim",
- "hd": false
- }
- ],
- "ip": -7,
- "op": 477,
- "st": 30,
- "bm": 0
- },
- {
- "ddd": 0,
- "ind": 21,
- "ty": 4,
- "nm": "Shape Layer 14",
- "sr": 1,
- "ks": {
- "o": {
- "a": 0,
- "k": 100,
- "ix": 11
- },
- "r": {
- "a": 0,
- "k": 90,
- "ix": 10
- },
- "p": {
- "a": 0,
- "k": [
- 151.32,
- 206.475,
- 0
- ],
- "ix": 2,
- "l": 2
- },
- "a": {
- "a": 0,
- "k": [
- 37.523,
- 788.471,
- 0
- ],
- "ix": 1,
- "l": 2
- },
- "s": {
- "a": 0,
- "k": [
- 17.09,
- 17.09,
- 100
- ],
- "ix": 6,
- "l": 2
- }
- },
- "ao": 0,
- "shapes": [
- {
- "ty": "gr",
- "it": [
- {
- "d": 1,
- "ty": "el",
- "s": {
- "a": 0,
- "k": [
- 793.047,
- 793.047
- ],
- "ix": 2
- },
- "p": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 3
- },
- "nm": "Ellipse Path 1",
- "mn": "ADBE Vector Shape - Ellipse",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.18431372549,
- 0.223529426724,
- 0.282352941176,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 1,
- "k": [
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 0.833
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0.167
- ]
- },
- "t": 69,
- "s": [
- 0
- ]
- },
- {
- "t": 79,
- "s": [
- 100
- ]
- }
- ],
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 34,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 4,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 37.523,
- 787.523
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100.278,
- 100.278
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Ellipse 1",
- "np": 3,
- "cix": 2,
- "bm": 0,
- "ix": 1,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "tm",
- "s": {
- "a": 0,
- "k": 0,
- "ix": 1
- },
- "e": {
- "a": 0,
- "k": 22.5,
- "ix": 2
- },
- "o": {
- "a": 0,
- "k": 365,
- "ix": 3
- },
- "m": 1,
- "ix": 2,
- "nm": "Trim Paths 1",
- "mn": "ADBE Vector Filter - Trim",
- "hd": false
- }
- ],
- "ip": -7,
- "op": 477,
- "st": 30,
- "bm": 0
- },
- {
- "ddd": 0,
- "ind": 22,
- "ty": 4,
- "nm": "Shape Layer 9",
- "sr": 1,
- "ks": {
- "o": {
- "a": 0,
- "k": 100,
- "ix": 11
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 10
- },
- "p": {
- "a": 0,
- "k": [
- 151.32,
- 206.475,
- 0
- ],
- "ix": 2,
- "l": 2
- },
- "a": {
- "a": 0,
- "k": [
- 37.523,
- 788.471,
- 0
- ],
- "ix": 1,
- "l": 2
- },
- "s": {
- "a": 0,
- "k": [
- 17.09,
- 17.09,
- 100
- ],
- "ix": 6,
- "l": 2
- }
- },
- "ao": 0,
- "shapes": [
- {
- "ty": "gr",
- "it": [
- {
- "d": 1,
- "ty": "el",
- "s": {
- "a": 0,
- "k": [
- 793.047,
- 793.047
- ],
- "ix": 2
- },
- "p": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 3
- },
- "nm": "Ellipse Path 1",
- "mn": "ADBE Vector Shape - Ellipse",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.541176470588,
- 0.705882352941,
- 0.972549079446,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 34,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 4,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 37.523,
- 787.523
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100.278,
- 100.278
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Ellipse 1",
- "np": 3,
- "cix": 2,
- "bm": 0,
- "ix": 1,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "tm",
- "s": {
- "a": 0,
- "k": 0,
- "ix": 1
- },
- "e": {
- "a": 1,
- "k": [
- {
- "i": {
- "x": [
- 0.2
- ],
- "y": [
- 1
- ]
- },
- "o": {
- "x": [
- 0.4
- ],
- "y": [
- 0
- ]
- },
- "t": 92,
- "s": [
- 0
- ]
- },
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 1
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0
- ]
- },
- "t": 138,
- "s": [
- 22.5
- ]
- },
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 1
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0
- ]
- },
- "t": 429,
- "s": [
- 22.5
- ]
- },
- {
- "t": 440,
- "s": [
- 26
- ]
- }
- ],
- "ix": 2
- },
- "o": {
- "a": 0,
- "k": 365,
- "ix": 3
- },
- "m": 1,
- "ix": 2,
- "nm": "Trim Paths 1",
- "mn": "ADBE Vector Filter - Trim",
- "hd": false
- }
- ],
- "ip": -7,
- "op": 477,
- "st": 30,
- "bm": 0
- },
- {
- "ddd": 0,
- "ind": 23,
- "ty": 4,
- "nm": "Shape Layer 6",
- "sr": 1,
- "ks": {
- "o": {
- "a": 0,
- "k": 100,
- "ix": 11
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 10
- },
- "p": {
- "a": 0,
- "k": [
- 151.32,
- 206.475,
- 0
- ],
- "ix": 2,
- "l": 2
- },
- "a": {
- "a": 0,
- "k": [
- 37.523,
- 788.471,
- 0
- ],
- "ix": 1,
- "l": 2
- },
- "s": {
- "a": 0,
- "k": [
- 17.09,
- 17.09,
- 100
- ],
- "ix": 6,
- "l": 2
- }
- },
- "ao": 0,
- "shapes": [
- {
- "ty": "gr",
- "it": [
- {
- "d": 1,
- "ty": "el",
- "s": {
- "a": 0,
- "k": [
- 793.047,
- 793.047
- ],
- "ix": 2
- },
- "p": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 3
- },
- "nm": "Ellipse Path 1",
- "mn": "ADBE Vector Shape - Ellipse",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 0.18431372549,
- 0.223529426724,
- 0.282352941176,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 1,
- "k": [
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 0.833
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0.167
- ]
- },
- "t": 69,
- "s": [
- 0
- ]
- },
- {
- "t": 79,
- "s": [
- 100
- ]
- }
- ],
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 34,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 4,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 37.523,
- 787.523
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100.278,
- 100.278
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Ellipse 1",
- "np": 3,
- "cix": 2,
- "bm": 0,
- "ix": 1,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "tm",
- "s": {
- "a": 0,
- "k": 0,
- "ix": 1
- },
- "e": {
- "a": 0,
- "k": 22.5,
- "ix": 2
- },
- "o": {
- "a": 0,
- "k": 365,
- "ix": 3
- },
- "m": 1,
- "ix": 2,
- "nm": "Trim Paths 1",
- "mn": "ADBE Vector Filter - Trim",
- "hd": false
- }
- ],
- "ip": -7,
- "op": 477,
- "st": 30,
- "bm": 0
- }
- ],
- "markers": []
-}
\ No newline at end of file
+{"v":"5.7.6","fr":60,"ip":0,"op":601,"w":1650,"h":2900,"nm":"UDFPS_EDU_LOTTIE_V02","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"PHONE_OUTLINE 2","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":571,"s":[0]},{"t":593.5,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[837,1430,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[929.1,929.1,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[5.243,0],[0,0],[0,5.244],[0,0],[-5.243,0],[0,0],[0,-5.244]],"o":[[0,5.244],[0,0],[-5.243,0],[0,0],[0,-5.244],[0,0],[5.243,0],[0,0]],"v":[[63.454,114.112],[53.945,123.622],[-55.413,123.622],[-64.922,114.112],[-64.922,-114.112],[-55.413,-123.622],[53.945,-123.622],[63.454,-114.112]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,1.313],[0,0],[1.313,0],[0,0],[6.554,0],[0,0],[0,-6.555],[0,0],[-6.554,0],[0,0],[0,6.555],[0,0],[0,1.313],[0,0],[1.313,0],[0,0]],"o":[[0,0],[0,-1.313],[0,0],[0,-6.555],[0,0],[-6.554,0],[0,0],[0,6.555],[0,0],[6.554,0],[0,0],[1.313,0],[0,0],[0,-1.313],[0,0],[1.313,0]],"v":[[68.209,-52.302],[68.209,-61.811],[65.832,-64.188],[65.832,-114.112],[53.945,-126],[-55.413,-126],[-67.3,-114.112],[-67.3,114.112],[-55.413,126],[53.945,126],[65.832,114.112],[65.832,-2.378],[68.209,-4.755],[68.209,-28.528],[65.832,-30.906],[65.832,-49.924]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.368627458811,0.368627458811,0.368627458811,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":467.5,"op":2942.5,"st":542.5,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-0.512,0.901,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-16.824,-0.768],[-4.154,11.903],[16.824,-9.075],[13.995,-11.903],[-4.154,6.247],[-13.996,-3.596]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.4,0.61568627451,0.988235294118,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Checkmark","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,13.798],[13.798,0],[0,-13.798],[-13.798,0]],"o":[[0,-13.798],[-13.798,0],[0,13.798],[13.798,0]],"v":[[25.345,-0.429],[0.322,-25.454],[-24.701,-0.429],[0.322,24.595]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.399993896484,0.615661621094,0.964691162109,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Outline","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":328,"op":2428,"st":328,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".black","cl":"black","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.78],"y":[0]},"t":472,"s":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":478,"s":[100]},{"i":{"x":[0],"y":[1]},"o":{"x":[0.52],"y":[0]},"t":548,"s":[100]},{"t":555,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1348.087,2521.152,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0,0,0.667],"y":[1.015,1.015,1]},"o":{"x":[0.363,0.363,0.333],"y":[0.038,0.038,0]},"t":473,"s":[0,0,100]},{"i":{"x":[0.474,0.474,0.667],"y":[1,1,1]},"o":{"x":[0.651,0.651,0.333],"y":[0.331,0.331,0]},"t":493,"s":[243.6,243.6,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"t":513,"s":[232,232,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"t":545,"s":[232,232,100]},{"t":555,"s":[0,0,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,12.703],[12.703,0],[0,-12.703],[-12.703,0]],"o":[[0,-12.703],[-12.703,0],[0,12.703],[12.703,0]],"v":[[23.037,0],[0,-23.038],[-23.037,0],[0,23.038]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":328,"op":2428,"st":328,"bm":0},{"ddd":0,"ind":5,"ty":3,"nm":"MAIN_MOVEMENT","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.07,"y":0.954},"o":{"x":0.64,"y":0.046},"t":143.928,"s":[837,2098,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.07,"y":0.07},"o":{"x":0.64,"y":0.64},"t":151.455,"s":[879,2057,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.07,"y":0.99},"o":{"x":0.64,"y":0.01},"t":219.176,"s":[879,2057,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.07,"y":0.07},"o":{"x":0.64,"y":0.64},"t":226.697,"s":[856,2015,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.07,"y":0.99},"o":{"x":0.64,"y":0},"t":295.674,"s":[856,2015,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.07,"y":0.07},"o":{"x":0.64,"y":0.64},"t":303.193,"s":[808,2019,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":1},"o":{"x":0.64,"y":0},"t":507.961,"s":[808,2019,0],"to":[0,0,0],"ti":[0,0,0]},{"t":521.345703125,"s":[837,2098,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.07,0.07,0.07],"y":[0.985,0.985,1]},"o":{"x":[0.64,0.64,0.64],"y":[0.015,0.015,0]},"t":90,"s":[105,105,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,1]},"o":{"x":[0.64,0.64,0.64],"y":[0,0,0]},"t":100.035,"s":[95,95,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"t":130.133,"s":[95,95,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,1.025]},"o":{"x":[0.439,0.439,0.439],"y":[0,0,0]},"t":135,"s":[105,105,100]},{"i":{"x":[0.07,0.07,0.07],"y":[0.701,0.701,1]},"o":{"x":[0.64,0.64,0.64],"y":[0.299,0.299,0]},"t":145,"s":[105,105,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":152.5,"s":[105,105,100]},{"i":{"x":[0.6,0.6,0.6],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,-0.833]},"t":157.5,"s":[105,105,100]},{"i":{"x":[0.07,0.07,0.07],"y":[0.97,0.97,1]},"o":{"x":[0.64,0.64,0.64],"y":[0.03,0.03,0]},"t":165.246,"s":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,1]},"o":{"x":[0.64,0.64,0.64],"y":[0,0,0]},"t":175.281,"s":[95,95,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"t":205.377,"s":[95,95,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.175]},"o":{"x":[0.341,0.341,0.341],"y":[0,0,0]},"t":210.391,"s":[100,100,100]},{"i":{"x":[0.07,0.07,0.07],"y":[1,1,1]},"o":{"x":[0.64,0.64,0.64],"y":[0,0,0]},"t":220,"s":[105,105,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":227.5,"s":[105,105,100]},{"i":{"x":[0.621,0.621,0.621],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.102]},"t":232.5,"s":[105,105,100]},{"i":{"x":[0.07,0.07,0.07],"y":[0.984,0.984,1]},"o":{"x":[0.64,0.64,0.64],"y":[0.016,0.016,0]},"t":240,"s":[105,105,100]},{"i":{"x":[0.07,0.07,0.07],"y":[1,1,1]},"o":{"x":[0.64,0.64,0.64],"y":[0,0,0]},"t":250.527,"s":[95,95,100]},{"i":{"x":[0.316,0.316,0.316],"y":[1,1,1]},"o":{"x":[0.64,0.64,0.64],"y":[0,0,0]},"t":285,"s":[95,95,100]},{"i":{"x":[0.577,0.577,0.577],"y":[1,1,1]},"o":{"x":[0.253,0.253,0.253],"y":[0,0,0]},"t":295,"s":[105,105,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,0.925]},"o":{"x":[0.299,0.299,0.299],"y":[0,0,0]},"t":302.5,"s":[105,105,100]},{"i":{"x":[0.627,0.627,0.627],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.262]},"t":307.5,"s":[105,105,100]},{"i":{"x":[0.07,0.07,0.07],"y":[0.984,0.984,1]},"o":{"x":[0.64,0.64,0.64],"y":[0.016,0.016,0]},"t":365,"s":[105,105,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,1]},"o":{"x":[0.64,0.64,0.64],"y":[0,0,0]},"t":375.771,"s":[95,95,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"t":508.369,"s":[95,95,100]},{"t":515,"s":[105,105,100]}],"ix":6,"l":2}},"ao":0,"ip":-70,"op":2517.5,"st":117.5,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".grey700","cl":"grey700","parent":5,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[3.5,-3,0],"ix":2,"l":2},"a":{"a":0,"k":[28,34,0],"ix":1,"l":2},"s":{"a":0,"k":[527,527,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[3.703,0],[2.328,1.76]],"o":[[-2.42,2.09],[-3.355,0],[0,0]],"v":[[9.038,-1.687],[-0.348,1.687],[-9.038,-1.118]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-7.847,0],[0,-7.095]],"o":[[-1.027,-2.676],[0,-7.095],[7.847,0],[0,0]],"v":[[-13.072,-9.314],[-14.099,-14.814],[-0.349,-27.648],[13.401,-14.814]],"c":false},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[2.75,0],[0.403,2.384],[0,0],[2.2,0],[-5.445,-1.54]],"o":[[0,0],[0,2.733],[-2.42,0],[0,0],[-0.367,-2.181],[-7.92,0],[0,0]],"v":[[13.401,-14.814],[13.401,-14.283],[8.433,-9.314],[3.538,-13.458],[3.025,-16.538],[-1.43,-20.314],[-0.642,-5.665]],"c":false},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ind":3,"ty":"sh","ix":4,"ks":{"a":0,"k":{"i":[[0,0],[-6.875,0],[-2.769,-4.327]],"o":[[2.768,-4.327],[6.876,0],[0,0]],"v":[[-15.933,-27.646],[-0.35,-34.979],[15.234,-27.646]],"c":false},"ix":2},"nm":"Path 4","mn":"ADBE Vector Shape - Group","hd":false},{"ind":4,"ty":"sh","ix":5,"ks":{"a":0,"k":{"i":[[0,0],[-3.666,0],[-2.97,-1.485]],"o":[[2.97,-1.485],[3.667,0],[0,0]],"v":[[-10.433,-39.985],[-0.35,-42.313],[9.734,-39.985]],"c":false},"ix":2},"nm":"Path 5","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.372549027205,0.388235300779,0.407843142748,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[27.933,54.313],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":6,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":90,"s":[100]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.64],"y":[0]},"t":110.035,"s":[0]},{"t":150.197,"s":[0],"h":1},{"t":152.705,"s":[100],"h":1},{"i":{"x":[0],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":165.246,"s":[100]},{"i":{"x":[0.833],"y":[-14.687]},"o":{"x":[0.64],"y":[0]},"t":185.281,"s":[0]},{"t":225.441,"s":[0],"h":1},{"t":227.949,"s":[100],"h":1},{"i":{"x":[0],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":240.494,"s":[100]},{"i":{"x":[0.833],"y":[-14.701]},"o":{"x":[0.64],"y":[0]},"t":260,"s":[0]},{"t":300.689,"s":[0],"h":1},{"t":303.193,"s":[100],"h":1},{"i":{"x":[0],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":365.74,"s":[100]},{"i":{"x":[0.833],"y":[-15.359]},"o":{"x":[0.64],"y":[0]},"t":385,"s":[0]},{"t":518.434,"s":[0],"h":1},{"t":520.943359375,"s":[100],"h":1}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.07],"y":[0.941]},"o":{"x":[0.64],"y":[0.059]},"t":130.133,"s":[100]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.64],"y":[0]},"t":140.146,"s":[0]},{"t":150.197,"s":[0],"h":1},{"t":152.705,"s":[100],"h":1},{"i":{"x":[0],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":205.377,"s":[100]},{"i":{"x":[0.833],"y":[-12.439]},"o":{"x":[0.64],"y":[0]},"t":215,"s":[0]},{"t":225.441,"s":[0],"h":1},{"t":227.949,"s":[100],"h":1},{"i":{"x":[0.07],"y":[0.941]},"o":{"x":[0.64],"y":[0.059]},"t":280.623,"s":[100]},{"i":{"x":[0.833],"y":[-12.342]},"o":{"x":[0.64],"y":[0]},"t":290.641,"s":[0]},{"t":300.689,"s":[0],"h":1},{"t":303.193,"s":[100],"h":1},{"i":{"x":[0.07],"y":[0.97]},"o":{"x":[0.64],"y":[0.03]},"t":508.369,"s":[100]},{"i":{"x":[0.833],"y":[-10.133]},"o":{"x":[0.64],"y":[0]},"t":513.385,"s":[0]},{"t":518.434,"s":[0],"h":1},{"t":520.943359375,"s":[100],"h":1}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":-20,"op":4855,"st":55,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":".blue400","cl":"blue400","parent":5,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[3.5,-3,0],"ix":2,"l":2},"a":{"a":0,"k":[28,34,0],"ix":1,"l":2},"s":{"a":0,"k":[527,527,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[3.703,0],[2.328,1.76]],"o":[[-2.42,2.09],[-3.355,0],[0,0]],"v":[[9.038,-1.687],[-0.348,1.687],[-9.038,-1.118]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.4,0.61568627451,0.964705882353,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[27.933,54.313],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-7.847,0],[0,-7.095]],"o":[[-1.027,-2.676],[0,-7.095],[7.847,0],[0,0]],"v":[[-12.723,9.167],[-13.75,3.667],[0,-9.167],[13.75,3.667]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.4,0.61568627451,0.964705882353,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[27.584,35.833],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[2.75,0],[0.403,2.384],[0,0],[2.2,0],[-5.445,-1.54]],"o":[[0,0],[0,2.733],[-2.42,0],[0,0],[-0.367,-2.181],[-7.92,0],[0,0]],"v":[[11.376,-1.824],[11.376,-1.293],[6.408,3.676],[1.512,-0.468],[0.999,-3.548],[-3.456,-7.324],[-2.667,7.324]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.4,0.61568627451,0.964705882353,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[29.958,41.324],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-6.875,0],[-2.769,-4.327]],"o":[[2.768,-4.327],[6.876,0],[0,0]],"v":[[-15.583,3.667],[-0.001,-3.667],[15.583,3.667]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.4,0.61568627451,0.964705882353,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[27.583,23.001],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":2,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-3.666,0],[-2.97,-1.485]],"o":[[2.97,-1.485],[3.667,0],[0,0]],"v":[[-10.083,1.164],[-0.001,-1.164],[10.083,1.164]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.4,0.61568627451,0.964705882353,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[27.583,13.164],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 5","np":2,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false}],"ip":-20,"op":4855,"st":55,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":".blue400","cl":"blue400","parent":5,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.88],"y":[0]},"t":88,"s":[40]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":113,"s":[0]},{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.88],"y":[0]},"t":128,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":153,"s":[40]},{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.88],"y":[0]},"t":158,"s":[40]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":183,"s":[0]},{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.88],"y":[0]},"t":198,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":223,"s":[40]},{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.88],"y":[0]},"t":230,"s":[40]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":255,"s":[0]},{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.88],"y":[0]},"t":280,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":295,"s":[40]},{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.88],"y":[0]},"t":368,"s":[40]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":383,"s":[0]},{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.88],"y":[0]},"t":508,"s":[0]},{"t":518,"s":[40]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[2.91,-13.59,0],"ix":2,"l":2},"a":{"a":0,"k":[-13.09,1270.41,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[440,440],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-13.09,1270.41],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-70,"op":2585,"st":117.5,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":".grey700","cl":"grey700","parent":5,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.88],"y":[0]},"t":88,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":113,"s":[40]},{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.88],"y":[0]},"t":128,"s":[40]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":153,"s":[0]},{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.88],"y":[0]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":183,"s":[40]},{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.88],"y":[0]},"t":198,"s":[40]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":223,"s":[0]},{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.88],"y":[0]},"t":230,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":255,"s":[40]},{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.88],"y":[0]},"t":280,"s":[40]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":295,"s":[0]},{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.88],"y":[0]},"t":368,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":383,"s":[40]},{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.88],"y":[0]},"t":508,"s":[40]},{"t":518,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[2.91,-13.59,0],"ix":2,"l":2},"a":{"a":0,"k":[-13.09,1270.41,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[440,440],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.372549027205,0.388235300779,0.407843142748,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-13.09,1270.41],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-70,"op":2585,"st":117.5,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":".grey600","cl":"grey600","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.88],"y":[0]},"t":12.5,"s":[100]},{"t":47.5,"s":[1]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[837,1430,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[929.094,929.094,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[5.243,0],[0,0],[0,5.244],[0,0],[-5.243,0],[0,0],[0,-5.244]],"o":[[0,5.244],[0,0],[-5.243,0],[0,0],[0,-5.244],[0,0],[5.243,0],[0,0]],"v":[[63.454,114.112],[53.945,123.622],[-55.413,123.622],[-64.922,114.112],[-64.922,-114.112],[-55.413,-123.622],[53.945,-123.622],[63.454,-114.112]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,1.313],[0,0],[1.313,0],[0,0],[6.554,0],[0,0],[0,-6.555],[0,0],[-6.554,0],[0,0],[0,6.555],[0,0],[0,1.313],[0,0],[1.313,0],[0,0]],"o":[[0,0],[0,-1.313],[0,0],[0,-6.555],[0,0],[-6.554,0],[0,0],[0,6.555],[0,0],[6.554,0],[0,0],[1.313,0],[0,0],[0,-1.313],[0,0],[1.313,0]],"v":[[68.209,-52.302],[68.209,-61.811],[65.832,-64.188],[65.832,-114.112],[53.945,-126],[-55.413,-126],[-67.3,-114.112],[-67.3,114.112],[-55.413,126],[53.945,126],[65.832,114.112],[65.832,-2.378],[68.209,-4.755],[68.209,-28.528],[65.832,-30.906],[65.832,-49.924]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-20,"op":2455,"st":55,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":547.5,"s":[100]},{"t":555,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.29],"y":[0]},"t":392.5,"s":[0]},{"t":618,"s":[630.722]}],"ix":10},"p":{"a":0,"k":[839.723,2083.641,0],"ix":2,"l":2},"a":{"a":0,"k":[-13.09,1270.41,0],"ix":1,"l":2},"s":{"a":0,"k":[125,125,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[1075,1075],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.88],"y":[0]},"t":92.535,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":141.172,"s":[25]},{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.88],"y":[0]},"t":168.826,"s":[25]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":215,"s":[50]},{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.88],"y":[0]},"t":242.439,"s":[50]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":290.633,"s":[75]},{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.88],"y":[0]},"t":335.787,"s":[75]},{"t":508.98046875,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.4,0.61568627451,0.964705882353,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":65,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-13.09,1270.41],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":4,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-70,"op":2585,"st":117.5,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.88],"y":[0]},"t":37.5,"s":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":60,"s":[40]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":550,"s":[40]},{"t":582.5,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[839.723,2083.641,0],"ix":2,"l":2},"a":{"a":0,"k":[-13.09,1270.41,0],"ix":1,"l":2},"s":{"a":0,"k":[125,125,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[1075,1075],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":65,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-13.09,1270.41],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-70,"op":2585,"st":117.5,"bm":0}],"markers":[{"tm":0,"cm":"0","dr":0},{"tm":292.5,"cm":"2","dr":0},{"tm":600,"cm":"3","dr":0}]}
\ No newline at end of file
diff --git a/res/values-sw600dp/config.xml b/res/values-sw600dp/config.xml
index 543dfee..f22d7ba 100644
--- a/res/values-sw600dp/config.xml
+++ b/res/values-sw600dp/config.xml
@@ -19,4 +19,6 @@
<!-- Dashboard number of columns -->
<integer name="dashboard_num_columns">2</integer>
+ <!-- Whether to support large screen -->
+ <bool name="config_supported_large_screen">true</bool>
</resources>
diff --git a/res/values-sw600dp/dimens.xml b/res/values-sw600dp/dimens.xml
index 45c28dd..b357758 100755
--- a/res/values-sw600dp/dimens.xml
+++ b/res/values-sw600dp/dimens.xml
@@ -63,6 +63,9 @@
<dimen name="confirm_credentials_side_margin">0dp</dimen>
<dimen name="confirm_credentials_top_margin">64dp</dimen>
+ <!-- padding for font size preview in large screen -->
+ <dimen name="font_size_preview_padding_start">32dp</dimen>
+
<!-- Padding for screen pinning -->
<dimen name="screen_pinning_padding_start">40dp</dimen>
<dimen name="screen_pinning_padding_end">40dp</dimen>
diff --git a/res/values/config.xml b/res/values/config.xml
index d83e10d..277176f 100755
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -532,6 +532,9 @@
<!-- Whether suw to support two panes -->
<bool name="config_suw_supported_two_panes">false</bool>
+ <!-- Whether to support large screen -->
+ <bool name="config_supported_large_screen">false</bool>
+
<!-- Display settings screen, Color mode options. Must be the same length and order as
config_color_mode_options_values below. Only the values that also appear in
frameworks/base/core/res/res/values/config.xml's config_availableColorModes are shown. -->
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 995742d..ed867d2 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -877,11 +877,9 @@
<!-- Dialog title shown when the user removes an enrollment [CHAR LIMIT=35] -->
<string name="security_settings_face_settings_remove_dialog_title">Delete face model?</string>
<!-- Dialog contents shown when the user removes an enrollment [CHAR LIMIT=NONE] -->
- <string name="security_settings_face_settings_remove_dialog_details">Your face model will be permanently and securely deleted. After deletion, you will need your PIN, pattern, or password to unlock your phone or for authentication in apps.</string>
- <!-- Dialog title shown when the user chooses to delete an existing enrolled face model. [CHAR LIMIT=35] -->
- <string name="security_settings_face_settings_remove_model_dialog_title">Delete face model?</string>
- <!-- Dialog contents shown when the user chooses to delete an existing enrolled face model. [CHAR LIMIT=NONE] -->
- <string name="security_settings_face_settings_remove_model_dialog_details">Your face model will be permanently and securely deleted.\n\nAfter deletion, you will need your fingerprint, PIN, pattern, or password to unlock your phone or for authentication in apps.</string>
+ <string name="security_settings_face_settings_remove_dialog_details">Your face model will be permanently and securely deleted.\n\nAfter deletion, you will need your PIN, pattern, or password to unlock your phone or for authentication in apps.</string>
+ <!-- Dialog contents shown when the user removes an enrollment when configured as a convenience [CHAR LIMIT=NONE] -->
+ <string name="security_settings_face_settings_remove_dialog_details_convenience">Your face model will be permanently and securely deleted.\n\nAfter deletion, you will need your PIN, pattern, or password to unlock your phone.</string>
<!-- Subtitle shown for contextual setting face enrollment [CHAR LIMIT=NONE] -->
<string name="security_settings_face_settings_context_subtitle">Use Face Unlock to unlock your phone</string>
@@ -1063,7 +1061,7 @@
<!-- Message shown in fingerprint enrollment dialog to begin enrollment [CHAR LIMIT=NONE] -->
<string name="security_settings_fingerprint_enroll_start_message">Put your finger on the sensor and lift after you feel a vibration</string>
<!-- Message shown in fingerprint enrollment dialog to begin enrollment [CHAR LIMIT=NONE] -->
- <string name="security_settings_udfps_enroll_start_message">Keep your finger on the sensor until you feel a vibration</string>
+ <string name="security_settings_udfps_enroll_start_message">Keep your fingerprint flat on the sensor until you feel a vibration</string>
<!-- Title shown in fingerprint enrollment [CHAR LIMIT=NONE]-->
<string name="security_settings_fingerprint_enroll_udfps_title">Touch & hold the fingerprint sensor</string>
<!-- Title shown in fingerprint enrollment dialog to repeat touching the fingerprint sensor [CHAR LIMIT=40] -->
@@ -1079,7 +1077,7 @@
<!-- Title shown during fingerprint enrollment that instructs the user to enroll their fingertip [CHAR LIMIT=80] -->
<string name="security_settings_udfps_enroll_fingertip_title">Place the tip of your finger on the sensor</string>
<!-- Title shown during fingerprint enrollment that instructs the user to enroll the edges of their finger [CHAR LIMIT=80] -->
- <string name="security_settings_udfps_enroll_edge_title">Finally, place the edges of your finger</string>
+ <string name="security_settings_udfps_enroll_edge_title">Finally, use the edges of your finger</string>
<!-- Message shown during fingerprint enrollment that instructs the user to enroll the edges of their finger [CHAR LIMIT=160] -->
<string name="security_settings_udfps_enroll_edge_message">Place the side of your fingerprint on the sensor and hold, then switch to the other side</string>
<!-- Message shown in fingerprint enrollment asking users to repeat touching the fingerprint sensor. [CHAR LIMIT=160] -->
@@ -4392,25 +4390,6 @@
<!-- Header on first screen of choose work profile pattern flow [CHAR LIMIT=40] -->
<string name="lockpassword_choose_your_profile_pattern_header">Set a work pattern</string>
- <!-- Header on first screen of choose device password flow [CHAR LIMIT=NONE] -->
- <string name="lockpassword_choose_password_description" product="phone">For added security, set a password to unlock the phone</string>
- <!-- Header on first screen of choose device PIN flow [CHAR LIMIT=NONE] -->
- <string name="lockpassword_choose_pin_description" product="phone">For added security, set a PIN to unlock the phone</string>
- <!-- Header on first screen of choose device pattern flow [CHAR LIMIT=NONE] -->
- <string name="lockpattern_choose_pattern_description" product="phone">For added security, set a pattern to unlock the phone</string>
- <!-- Header on first screen of choose device password flow [CHAR LIMIT=NONE] -->
- <string name="lockpassword_choose_password_description" product="tablet">For added security, set a password to unlock the tablet</string>
- <!-- Header on first screen of choose device PIN flow [CHAR LIMIT=NONE] -->
- <string name="lockpassword_choose_pin_description" product="tablet">For added security, set a PIN to unlock the tablet</string>
- <!-- Header on first screen of choose device pattern flow [CHAR LIMIT=NONE] -->
- <string name="lockpattern_choose_pattern_description" product="tablet">For added security, set a pattern to unlock the tablet</string>
- <!-- Header on first screen of choose device password flow [CHAR LIMIT=NONE] -->
- <string name="lockpassword_choose_password_description" product="default">For added security, set a password to unlock the device</string>
- <!-- Header on first screen of choose device PIN flow [CHAR LIMIT=NONE] -->
- <string name="lockpassword_choose_pin_description" product="default">For added security, set a PIN to unlock the device</string>
- <!-- Header on first screen of choose device pattern flow [CHAR LIMIT=NONE] -->
- <string name="lockpattern_choose_pattern_description" product="default">For added security, set a pattern to unlock the device</string>
-
<!-- Header on first screen of choose password/PIN as backup for fingerprint flow. If this string cannot be translated in under 40 characters, please translate "Set fingerprint backup" [CHAR LIMIT=40] -->
<string name="lockpassword_choose_your_password_header_for_fingerprint">To use fingerprint, set password</string>
<!-- Header on first screen of choose pattern as backup for fingerprint flow. If this string cannot be translated in under 40 characters, please translate "Set fingerprint backup" [CHAR LIMIT=40] -->
@@ -5296,13 +5275,13 @@
<!-- Message of the magnification mode option to choose the magnification mode. [CHAR LIMIT=none] -->
<string name="accessibility_magnification_area_settings_mode_switch_summary">Tap the switch button to move between both options</string>
<!-- Title for the accessibility magnification switch shortcut dialog. [CHAR LIMIT=48] -->
- <string name="accessibility_magnification_switch_shortcut_title">Switch to accessibility button?</string>
+ <string name="accessibility_magnification_switch_shortcut_title">This may slow down your keyboard</string>
<!-- Message for the accessibility magnification switch shortcut dialog. [CHAR LIMIT=none] -->
- <string name="accessibility_magnification_switch_shortcut_message">Using triple-tap to magnify part of your screen causes typing and other delays.\n\nThe accessibility button floats on your screen over other apps. Tap it to magnify.</string>
- <!-- Title for the switch shortcut button in accessibility switch shortcut dialog to change the config shortcut value. [CHAR LIMIT=45] -->
- <string name="accessibility_magnification_switch_shortcut_positive_button">Switch to accessibility button</string>
- <!-- Title for the cancel button in accessibility switch shortcut dialog to keep the config shortcut value. [CHAR LIMIT=54] -->
- <string name="accessibility_magnification_switch_shortcut_negative_button">Use triple-tap</string>
+ <string name="accessibility_magnification_switch_shortcut_message">When using triple-tap to magnify part of your screen, you may notice issues over the keyboard.\n\nTo avoid this, you can change your magnification shortcut from triple-tap to another option.\n<annotation id="link">Change setting</annotation></string>
+ <!-- Title for the switch shortcut button in accessibility switch shortcut dialog to confirm the action. [CHAR LIMIT=45] -->
+ <string name="accessibility_magnification_switch_shortcut_positive_button">Continue anyway</string>
+ <!-- Title for the cancel button in accessibility switch shortcut dialog to go back to edit. [CHAR LIMIT=54] -->
+ <string name="accessibility_magnification_switch_shortcut_negative_button">Cancel</string>
<!-- Title for the accessibility preference screen to enable screen magnification settings. [CHAR LIMIT=35] -->
<string name="accessibility_magnification_service_settings_title">Magnification settings</string>
<!-- Title for the accessibility preference screen to enable triple-tap gesture screen magnification. [CHAR LIMIT=35] -->
@@ -8128,11 +8107,17 @@
<!-- Checkbox to always use for calls. [CHAR LIMIT=40] -->
<string name="sim_calls_always_use">Always use this for calls</string>
<!-- Message for selecting sim for data in settings. [CHAR LIMIT=40] -->
- <string name="select_sim_for_data">Select a SIM for data</string>
+ <string name="select_sim_for_data">Choose SIM for mobile data</string>
<!-- Message for selecting sim for SMS in settings. [CHAR LIMIT=40] -->
<string name="select_sim_for_sms">Select a SIM for SMS</string>
<!-- Message for switching data SIM; switching takes a while -->
<string name="data_switch_started">Switching data SIM, this may take up to a minute\u2026</string>
+ <!-- Title for selecting specific sim for data in settings. [CHAR LIMIT=40] -->
+ <string name="select_specific_sim_for_data_title">Use <xliff:g id="new_sim" example="carrierA">%1$s</xliff:g> for mobile data?</string>
+ <!-- Message for selecting specific sim for data in settings. [CHAR LIMIT=NONE] -->
+ <string name="select_specific_sim_for_data_msg">If you switch to <xliff:g id="new_sim" example="carrierA">%1$s</xliff:g>, <xliff:g id="old_sim" example="carrierB">%2$s</xliff:g> will no longer be used for mobile data.</string>
+ <!-- Button on a selecting specific sim dialog to confirm data in settings. [CHAR LIMIT=40] -->
+ <string name="select_specific_sim_for_data_button">Use <xliff:g id="new_sim" example="carrierA">%1$s</xliff:g></string>
<!-- Message for selecting sim for call in settings. [CHAR LIMIT=40] -->
<string name="select_sim_for_calls">Call with</string>
<!-- Title for selecting a SIM card. [CHAR LIMIT=40] -->
@@ -12942,14 +12927,22 @@
<string name="sim_action_switch_sub_dialog_title">Switch to <xliff:g id="carrier_name" example="Google Fi">%1$s</xliff:g>?</string>
<!-- Title of confirmation dialog asking the user if they want to switch to the SIM card. [CHAR_LIMIT=NONE] -->
<string name="sim_action_switch_psim_dialog_title">Switch to using SIM card?</string>
+ <!-- Title of confirmation dialog asking the user if they want to switch subscription. [CHAR_LIMIT=NONE] -->
+ <string name="sim_action_switch_sub_dialog_mep_title">Use <xliff:g id="carrier_name" example="Google Fi">%1$s</xliff:g>?</string>
<!-- Body text of confirmation dialog for switching subscription that involves switching SIM slots. Indicates that only one SIM can be active at a time. Also that switching will not cancel the user's mobile service plan. [CHAR_LIMIT=NONE] -->
<string name="sim_action_switch_sub_dialog_text">Only one SIM can be active at a time.\n\nSwitching to <xliff:g id="to_carrier_name" example="Google Fi">%1$s</xliff:g> won\u2019t cancel your <xliff:g id="from_carrier_name" example="Sprint">%2$s</xliff:g> service.</string>
<!-- Body text of confirmation dialog for switching subscription between two eSIM profiles. Indicates that only one downloaded SIM can be active at a time. Also that switching will not cancel the user's mobile service plan. [CHAR_LIMIT=NONE] -->
<string name="sim_action_switch_sub_dialog_text_downloaded">Only one downloaded SIM can be active at a time.\n\nSwitching to <xliff:g id="to_carrier_name" example="Google Fi">%1$s</xliff:g> won\u2019t cancel your <xliff:g id="from_carrier_name" example="Sprint">%2$s</xliff:g> service.</string>
<!-- Body text of confirmation dialog for switching subscription between two eSIM profiles. Indicates that only one SIM can be active at a time. Also that switching will not cancel the user's mobile service plan. [CHAR_LIMIT=NONE] -->
<string name="sim_action_switch_sub_dialog_text_single_sim">Only one SIM can be active at a time.\n\nSwitching won\u2019t cancel your <xliff:g id="to_carrier_name" example="Google Fi">%1$s</xliff:g> service.</string>
+ <!-- Body text of confirmation dialog for switching subscription between two eSIM profiles. Indicates that only one downloaded SIM can be active at a time. Also that switching will not cancel the user's mobile service plan. [CHAR_LIMIT=NONE] -->
+ <string name="sim_action_switch_sub_dialog_mep_text">You can use 2 SIMs at a time. To use <xliff:g id="carrier_name" example="Google Fi">%1$s</xliff:g>, turn off another SIM.</string>
<!-- Text of confirm button in the confirmation dialog asking the user if they want to switch subscription. [CHAR_LIMIT=NONE] -->
<string name="sim_action_switch_sub_dialog_confirm">Switch to <xliff:g id="carrier_name" example="Google Fi">%1$s</xliff:g></string>
+ <!-- Text of carrier list item in the mep confirmation dialog asking the user if they want to turn off the carrier. [CHAR_LIMIT=NONE] -->
+ <string name="sim_action_switch_sub_dialog_carrier_list_item_for_turning_off">Turn off <xliff:g id="carrier_name" example="Google Fi">%1$s</xliff:g></string>
+ <!-- Text of carrier list item in the mep confirmation dialog asking the user if they want to turn off the carrier. [CHAR_LIMIT=NONE] -->
+ <string name="sim_action_switch_sub_dialog_info_outline_for_turning_off">Turning off a SIM won\u2019t cancel your service</string>
<!-- Status message indicating the device is in the process of disconnecting from one mobile network and immediately connecting to another. [CHAR_LIMIT=NONE] -->
<string name="sim_action_enabling_sim_without_carrier_name">Connecting to network…</string>
<!-- Text of progress dialog indicating the subscription switch is in progress. [CHAR_LIMIT=NONE] -->
diff --git a/res/values/themes.xml b/res/values/themes.xml
index 7c5c111..d65c1b3 100644
--- a/res/values/themes.xml
+++ b/res/values/themes.xml
@@ -220,6 +220,10 @@
<item name="android:statusBarColor">?attr/colorPrimaryDark</item>
</style>
+ <style name="Theme.Settings.Home.DeepLink">
+ <item name="android:windowAnimationStyle">@null</item>
+ </style>
+
<style name="Theme.Settings.ContextualCard" parent="Theme.Settings.Home">
<item name="android:textAppearanceListItem">@style/TextAppearance.HomepageCardTitle</item>
</style>
diff --git a/res/xml/accounts_dashboard_settings_header.xml b/res/xml/accounts_dashboard_settings_header.xml
new file mode 100644
index 0000000..99f0736
--- /dev/null
+++ b/res/xml/accounts_dashboard_settings_header.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+ 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
+
+ http://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.
+-->
+
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:settings="http://schemas.android.com/apk/res-auto"
+ android:title="@string/account_dashboard_title"
+ settings:searchable="false">
+</PreferenceScreen>
diff --git a/res/xml/language_and_input.xml b/res/xml/language_and_input.xml
index 2055ab7..f33ef5c 100644
--- a/res/xml/language_and_input.xml
+++ b/res/xml/language_and_input.xml
@@ -91,13 +91,6 @@
settings:searchable="false">
<Preference
- android:key="virtual_keyboards_for_work_pref"
- android:title="@string/virtual_keyboards_for_work_title"
- android:fragment="com.android.settings.inputmethod.AvailableVirtualKeyboardFragment"
- settings:forWork="true"
- settings:controller="com.android.settings.inputmethod.VirtualKeyboardForWorkPreferenceController" />
-
- <Preference
android:key="spellcheckers_settings_for_work_pref"
android:title="@string/spellcheckers_settings_for_work_title"
android:fragment="com.android.settings.inputmethod.SpellCheckersSettings"
diff --git a/res/xml/location_recent_requests_header.xml b/res/xml/location_recent_requests_header.xml
new file mode 100644
index 0000000..0e252a5
--- /dev/null
+++ b/res/xml/location_recent_requests_header.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+ 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
+
+ http://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.
+-->
+
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:settings="http://schemas.android.com/apk/res-auto"
+ android:title="@string/location_category_recent_location_requests"
+ settings:searchable="false">
+</PreferenceScreen>
diff --git a/res/xml/location_services_header.xml b/res/xml/location_services_header.xml
new file mode 100644
index 0000000..4eaf2c5
--- /dev/null
+++ b/res/xml/location_services_header.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+ 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
+
+ http://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.
+-->
+
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:settings="http://schemas.android.com/apk/res-auto"
+ android:title="@string/location_services_preference_title"
+ settings:searchable="false">
+</PreferenceScreen>
diff --git a/res/xml/location_settings_header.xml b/res/xml/location_settings_header.xml
new file mode 100644
index 0000000..4749a2e
--- /dev/null
+++ b/res/xml/location_settings_header.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+ 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
+
+ http://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.
+-->
+
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:settings="http://schemas.android.com/apk/res-auto"
+ android:title="@string/location_settings_title"
+ settings:searchable="false">
+</PreferenceScreen>
diff --git a/res/xml/mobile_network_settings.xml b/res/xml/mobile_network_settings.xml
index 7d1ff09..673994a 100644
--- a/res/xml/mobile_network_settings.xml
+++ b/res/xml/mobile_network_settings.xml
@@ -223,7 +223,6 @@
<Preference
android:key="choose_network_key"
android:title="@string/choose_network_title"
- android:fragment="com.android.phone.NetworkSelectSetting"
settings:controller="com.android.settings.network.telephony.gsm.OpenNetworkSelectPagePreferenceController"/>
</PreferenceCategory>
diff --git a/res/xml/my_device_info.xml b/res/xml/my_device_info.xml
index 35082fd..9547318 100644
--- a/res/xml/my_device_info.xml
+++ b/res/xml/my_device_info.xml
@@ -52,7 +52,7 @@
settings:controller="com.android.settings.deviceinfo.BrandedAccountPreferenceController"/>
<!-- Phone number -->
- <Preference
+ <com.android.settings.deviceinfo.PhoneNumberSummaryPreference
android:key="phone_number"
android:order="3"
android:title="@string/status_number"
@@ -113,7 +113,7 @@
settings:controller="com.android.settings.deviceinfo.HardwareInfoPreferenceController"/>
<!-- IMEI -->
- <Preference
+ <com.android.settings.deviceinfo.PhoneNumberSummaryPreference
android:key="imei_info"
android:order="32"
android:title="@string/status_imei"
diff --git a/res/xml/wifi_calling_settings.xml b/res/xml/wifi_calling_settings.xml
index 0276bdb..902ff1a 100644
--- a/res/xml/wifi_calling_settings.xml
+++ b/res/xml/wifi_calling_settings.xml
@@ -21,6 +21,7 @@
<com.android.settings.wifi.calling.ListWithEntrySummaryPreference
android:key="wifi_calling_mode"
+ isPreferenceVisible="false"
android:title="@string/wifi_calling_mode_title"
android:summary="@string/wifi_calling_mode_title"
android:entries="@array/wifi_calling_mode_choices"
@@ -30,6 +31,7 @@
<com.android.settings.wifi.calling.ListWithEntrySummaryPreference
android:key="wifi_calling_roaming_mode"
+ isPreferenceVisible="false"
android:title="@string/wifi_calling_roaming_mode_title"
android:summary="@string/wifi_calling_roaming_mode_summary"
android:entries="@array/wifi_calling_mode_choices_v2"
@@ -39,7 +41,12 @@
<Preference
android:key="emergency_address_key"
+ isPreferenceVisible="false"
android:title="@string/emergency_address_title"
android:summary="@string/emergency_address_summary" />
+ <com.android.settings.wifi.calling.LinkifyDescriptionPreference
+ android:key="no_options_description"
+ isPreferenceVisible="false" />
+
</PreferenceScreen>
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 9e3d7e6..afd0d15 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -90,6 +90,7 @@
public static class PublicVolumeSettingsActivity extends SettingsActivity { /* empty */ }
public static class WifiSettingsActivity extends SettingsActivity { /* empty */ }
public static class NetworkProviderSettingsActivity extends SettingsActivity { /* empty */ }
+ public static class NetworkSelectActivity extends SettingsActivity { /* empty */ }
/** Activity for the Wi-Fi network details settings. */
public static class WifiDetailsSettingsActivity extends SettingsActivity { /* empty */ }
public static class WifiP2pSettingsActivity extends SettingsActivity { /* empty */ }
@@ -123,6 +124,8 @@
public static class AccessibilityDaltonizerSettingsActivity extends SettingsActivity { /* empty */ }
/** Activity for lockscreen settings. */
public static class LockScreenSettingsActivity extends SettingsActivity { /* empty */ }
+ /** Activity for bluetooth pairing settings. */
+ public static class BlueToothPairingActivity extends SettingsActivity { /* empty */ }
/** Activity for Reduce Bright Colors. */
public static class ReduceBrightColorsSettingsActivity extends SettingsActivity { /* empty */ }
/** Activity for the security dashboard. */
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index 2b5f695..d3d3604 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -377,8 +377,9 @@
public static Intent getTrampolineIntent(Intent intent, String highlightMenuKey) {
final Intent detailIntent = new Intent(intent);
// It's a deep link intent, SettingsHomepageActivity will set SplitPairRule and start it.
- final Intent trampolineIntent = new Intent(ACTION_SETTINGS_EMBED_DEEP_LINK_ACTIVITY);
- trampolineIntent.replaceExtras(detailIntent);
+ final Intent trampolineIntent = new Intent(ACTION_SETTINGS_EMBED_DEEP_LINK_ACTIVITY)
+ .setPackage(Utils.SETTINGS_PACKAGE_NAME)
+ .replaceExtras(detailIntent);
// Relay detail intent data to prevent failure of Intent#ParseUri.
// If Intent#getData() is not null, Intent#toUri will return an Uri which has the scheme of
diff --git a/src/com/android/settings/accessibility/AccessibilityScreenSizeForSetupWizardActivity.java b/src/com/android/settings/accessibility/AccessibilityScreenSizeForSetupWizardActivity.java
index 10a0bce..7c8076f 100644
--- a/src/com/android/settings/accessibility/AccessibilityScreenSizeForSetupWizardActivity.java
+++ b/src/com/android/settings/accessibility/AccessibilityScreenSizeForSetupWizardActivity.java
@@ -120,8 +120,8 @@
: R.string.screen_zoom_title);
((TextView) findViewById(R.id.sud_layout_subtitle)).setText(
getFragmentType(getIntent()) == FragmentType.FONT_SIZE
- ? R.string.short_summary_font_size
- : R.string.screen_zoom_short_summary);
+ ? R.string.font_size_summary
+ : R.string.screen_zoom_summary);
}
private boolean isSuwSupportedTwoPanes() {
diff --git a/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizardActivity.java b/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizardActivity.java
index 3a6bea9..7a28e39 100644
--- a/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizardActivity.java
+++ b/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizardActivity.java
@@ -38,7 +38,6 @@
import com.android.settings.support.actionbar.HelpResourceProvider;
import com.android.settingslib.core.instrumentation.Instrumentable;
import com.android.settingslib.transition.SettingsTransitionHelper;
-import com.android.settingslib.transition.SettingsTransitionHelper.TransitionType;
import com.google.android.setupcompat.util.WizardManagerHelper;
import com.google.android.setupdesign.util.ThemeHelper;
@@ -130,7 +129,6 @@
final Intent intent = new Intent(this,
AccessibilityScreenSizeForSetupWizardActivity.class);
intent.putExtra(VISION_FRAGMENT_NO, FragmentType.FONT_SIZE);
- intent.putExtra(EXTRA_PAGE_TRANSITION_TYPE, TransitionType.TRANSITION_FADE);
startActivity(intent);
Log.d(LOG_TAG, "Launch font size settings");
finish();
diff --git a/src/com/android/settings/accessibility/LaunchAccessibilityActivityPreferenceFragment.java b/src/com/android/settings/accessibility/LaunchAccessibilityActivityPreferenceFragment.java
index 3b15830..9666fe9 100644
--- a/src/com/android/settings/accessibility/LaunchAccessibilityActivityPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/LaunchAccessibilityActivityPreferenceFragment.java
@@ -150,6 +150,7 @@
private void initLaunchPreference() {
final Preference launchPreference = new Preference(getPrefContext());
+ launchPreference.setLayoutResource(R.layout.accessibility_launch_activity_preference);
launchPreference.setKey(KEY_LAUNCH_PREFERENCE);
final AccessibilityShortcutInfo info = getAccessibilityShortcutInfo();
diff --git a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
index c25abf3..233b7ee 100644
--- a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
@@ -143,9 +143,7 @@
setPreferenceScreen(preferenceScreen);
}
- final List<String> shortcutFeatureKeys = new ArrayList<>();
- shortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS);
- shortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE);
+ final List<String> shortcutFeatureKeys = getFeatureSettingsKeys();
mSettingsContentObserver = new SettingsContentObserver(new Handler(), shortcutFeatureKeys) {
@Override
public void onChange(boolean selfChange, Uri uri) {
@@ -155,6 +153,13 @@
};
}
+ protected List<String> getFeatureSettingsKeys() {
+ final List<String> shortcutFeatureKeys = new ArrayList<>();
+ shortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS);
+ shortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE);
+ return shortcutFeatureKeys;
+ }
+
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
diff --git a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java
index 6b4a5f2..1586c5a 100644
--- a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java
@@ -276,6 +276,13 @@
}
@Override
+ protected List<String> getFeatureSettingsKeys() {
+ final List<String> shortcutKeys = super.getFeatureSettingsKeys();
+ shortcutKeys.add(Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED);
+ return shortcutKeys;
+ }
+
+ @Override
protected CharSequence getShortcutTypeSummary(Context context) {
if (!mShortcutPreference.isChecked()) {
return context.getText(R.string.switch_off_text);
diff --git a/src/com/android/settings/accounts/RemoveAccountPreferenceController.java b/src/com/android/settings/accounts/RemoveAccountPreferenceController.java
index 037f584..2ce2206 100644
--- a/src/com/android/settings/accounts/RemoveAccountPreferenceController.java
+++ b/src/com/android/settings/accounts/RemoveAccountPreferenceController.java
@@ -53,6 +53,7 @@
public class RemoveAccountPreferenceController extends AbstractPreferenceController
implements PreferenceControllerMixin, OnClickListener {
+ private static final String TAG = "RemoveAccountPrefController";
private static final String KEY_REMOVE_ACCOUNT = "remove_account";
private final MetricsFeatureProvider mMetricsFeatureProvider;
@@ -175,10 +176,11 @@
| IOException
| AuthenticatorException e) {
// handled below
- }
- if (failed) {
+ Log.w(TAG, "Remove account error: " + e);
RemoveAccountFailureDialog.show(getTargetFragment());
- } else {
+ }
+ Log.i(TAG, "failed: " + failed);
+ if (!failed) {
targetActivity.finish();
}
}, null, mUserHandle);
@@ -210,7 +212,7 @@
final Context context = getActivity();
return new AlertDialog.Builder(context)
- .setTitle(R.string.really_remove_account_title)
+ .setTitle(R.string.remove_account_label)
.setMessage(R.string.remove_account_failed)
.setPositiveButton(android.R.string.ok, null)
.create();
diff --git a/src/com/android/settings/activityembedding/ActivityEmbeddingRulesController.java b/src/com/android/settings/activityembedding/ActivityEmbeddingRulesController.java
index fa61994..8484324 100644
--- a/src/com/android/settings/activityembedding/ActivityEmbeddingRulesController.java
+++ b/src/com/android/settings/activityembedding/ActivityEmbeddingRulesController.java
@@ -23,7 +23,6 @@
import android.util.LayoutDirection;
import android.util.Log;
-import androidx.annotation.NonNull;
import androidx.window.embedding.ActivityFilter;
import androidx.window.embedding.ActivityRule;
import androidx.window.embedding.SplitController;
@@ -114,7 +113,7 @@
registerTwoPanePairRule(
context,
- getComponentName(context, Settings.class),
+ new ComponentName(context, Settings.class),
secondaryComponent,
secondaryIntentAction,
finishPrimaryWithSecondary ? SplitRule.FINISH_ADJACENT : SplitRule.FINISH_NEVER,
@@ -123,7 +122,7 @@
registerTwoPanePairRule(
context,
- getComponentName(context, SettingsHomepageActivity.class),
+ new ComponentName(context, SettingsHomepageActivity.class),
secondaryComponent,
secondaryIntentAction,
finishPrimaryWithSecondary ? SplitRule.FINISH_ADJACENT : SplitRule.FINISH_NEVER,
@@ -143,7 +142,7 @@
registerTwoPanePairRule(
context,
- getComponentName(context, SliceDeepLinkHomepageActivity.class),
+ new ComponentName(context, SliceDeepLinkHomepageActivity.class),
secondaryComponent,
secondaryIntentAction,
finishPrimaryWithSecondary ? SplitRule.FINISH_ALWAYS : SplitRule.FINISH_NEVER,
@@ -179,7 +178,7 @@
registerTwoPanePairRuleForSettingsHome(
context,
- getComponentName(context, SubSettings.class),
+ new ComponentName(context, SubSettings.class),
null /* secondaryIntentAction */,
clearTop);
}
@@ -191,8 +190,7 @@
addActivityFilter(activityFilters, SliceDeepLinkHomepageActivity.class);
addActivityFilter(activityFilters, Settings.class);
- final Intent intent = new Intent();
- intent.setComponent(getComponentName(Settings.NetworkDashboardActivity.class));
+ final Intent intent = new Intent(mContext, Settings.NetworkDashboardActivity.class);
final SplitPlaceholderRule placeholderRule = new SplitPlaceholderRule(
activityFilters,
intent,
@@ -215,23 +213,7 @@
private void addActivityFilter(Set<ActivityFilter> activityFilters,
Class<? extends Activity> activityClass) {
- activityFilters.add(new ActivityFilter(getComponentName(activityClass),
+ activityFilters.add(new ActivityFilter(new ComponentName(mContext, activityClass),
null /* intentAction */));
}
-
- private void addActivityFilter(Set<ActivityFilter> activityFilters,
- ComponentName componentName) {
- activityFilters.add(new ActivityFilter(componentName, null /* intentAction */));
- }
-
- @NonNull
- private ComponentName getComponentName(Class<? extends Activity> activityClass) {
- return getComponentName(mContext, activityClass);
- }
-
- @NonNull
- private static ComponentName getComponentName(Context context,
- Class<? extends Activity> activityClass) {
- return new ComponentName(context.getPackageName(), activityClass.getName());
- }
}
diff --git a/src/com/android/settings/applications/manageapplications/ManageApplications.java b/src/com/android/settings/applications/manageapplications/ManageApplications.java
index c1f4574..7b5c221 100644
--- a/src/com/android/settings/applications/manageapplications/ManageApplications.java
+++ b/src/com/android/settings/applications/manageapplications/ManageApplications.java
@@ -272,8 +272,7 @@
Intent intent = activity.getIntent();
Bundle args = getArguments();
- int screenTitle = intent.getIntExtra(
- SettingsActivity.EXTRA_SHOW_FRAGMENT_TITLE_RESID, R.string.all_apps);
+ final int screenTitle = getTitleResId(intent, args);
String className = args != null ? args.getString(EXTRA_CLASSNAME) : null;
if (className == null) {
className = intent.getComponent().getClassName();
@@ -290,49 +289,36 @@
mSortOrder = R.id.sort_order_size;
} else if (className.equals(UsageAccessSettingsActivity.class.getName())) {
mListType = LIST_TYPE_USAGE_ACCESS;
- screenTitle = R.string.usage_access;
} else if (className.equals(HighPowerApplicationsActivity.class.getName())) {
mListType = LIST_TYPE_HIGH_POWER;
// Default to showing system.
mShowSystem = true;
- screenTitle = R.string.high_power_apps;
} else if (className.equals(OverlaySettingsActivity.class.getName())) {
mListType = LIST_TYPE_OVERLAY;
- screenTitle = R.string.system_alert_window_settings;
reportIfRestrictedSawIntent(intent);
} else if (className.equals(WriteSettingsActivity.class.getName())) {
mListType = LIST_TYPE_WRITE_SETTINGS;
- screenTitle = R.string.write_settings;
} else if (className.equals(ManageExternalSourcesActivity.class.getName())) {
mListType = LIST_TYPE_MANAGE_SOURCES;
- screenTitle = R.string.install_other_apps;
} else if (className.equals(GamesStorageActivity.class.getName())) {
mListType = LIST_TYPE_GAMES;
mSortOrder = R.id.sort_order_size;
} else if (className.equals(Settings.ChangeWifiStateActivity.class.getName())) {
mListType = LIST_TYPE_WIFI_ACCESS;
- screenTitle = R.string.change_wifi_state_title;
} else if (className.equals(Settings.ManageExternalStorageActivity.class.getName())) {
mListType = LIST_MANAGE_EXTERNAL_STORAGE;
- screenTitle = R.string.manage_external_storage_title;
} else if (className.equals(Settings.MediaManagementAppsActivity.class.getName())) {
mListType = LIST_TYPE_MEDIA_MANAGEMENT_APPS;
- screenTitle = R.string.media_management_apps_title;
} else if (className.equals(Settings.AlarmsAndRemindersActivity.class.getName())) {
mListType = LIST_TYPE_ALARMS_AND_REMINDERS;
- screenTitle = R.string.alarms_and_reminders_title;
} else if (className.equals(Settings.NotificationAppListActivity.class.getName())) {
mListType = LIST_TYPE_NOTIFICATION;
mUsageStatsManager = IUsageStatsManager.Stub.asInterface(
ServiceManager.getService(Context.USAGE_STATS_SERVICE));
mNotificationBackend = new NotificationBackend();
mSortOrder = R.id.sort_order_recent_notification;
- screenTitle = R.string.app_notifications_title;
} else {
- if (screenTitle == -1) {
- screenTitle = R.string.all_apps;
- }
mListType = LIST_TYPE_MAIN;
}
final AppFilterRegistry appFilterRegistry = AppFilterRegistry.getInstance();
@@ -881,6 +867,46 @@
params.setBehavior(behavior);
}
+ /**
+ * Returns a resource ID of title based on what type of app list is
+ * @param intent the intent of the activity that might include a specified title
+ * @param args the args that includes a class name of app list
+ */
+ public static int getTitleResId(@NonNull Intent intent, Bundle args) {
+ int screenTitle = intent.getIntExtra(
+ SettingsActivity.EXTRA_SHOW_FRAGMENT_TITLE_RESID, R.string.all_apps);
+ String className = args != null ? args.getString(EXTRA_CLASSNAME) : null;
+ if (className == null) {
+ className = intent.getComponent().getClassName();
+ }
+ if (className.equals(Settings.UsageAccessSettingsActivity.class.getName())) {
+ screenTitle = R.string.usage_access;
+ } else if (className.equals(Settings.HighPowerApplicationsActivity.class.getName())) {
+ screenTitle = R.string.high_power_apps;
+ } else if (className.equals(Settings.OverlaySettingsActivity.class.getName())) {
+ screenTitle = R.string.system_alert_window_settings;
+ } else if (className.equals(Settings.WriteSettingsActivity.class.getName())) {
+ screenTitle = R.string.write_settings;
+ } else if (className.equals(Settings.ManageExternalSourcesActivity.class.getName())) {
+ screenTitle = R.string.install_other_apps;
+ } else if (className.equals(Settings.ChangeWifiStateActivity.class.getName())) {
+ screenTitle = R.string.change_wifi_state_title;
+ } else if (className.equals(Settings.ManageExternalStorageActivity.class.getName())) {
+ screenTitle = R.string.manage_external_storage_title;
+ } else if (className.equals(Settings.MediaManagementAppsActivity.class.getName())) {
+ screenTitle = R.string.media_management_apps_title;
+ } else if (className.equals(Settings.AlarmsAndRemindersActivity.class.getName())) {
+ screenTitle = R.string.alarms_and_reminders_title;
+ } else if (className.equals(Settings.NotificationAppListActivity.class.getName())) {
+ screenTitle = R.string.app_notifications_title;
+ } else {
+ if (screenTitle == -1) {
+ screenTitle = R.string.all_apps;
+ }
+ }
+ return screenTitle;
+ }
+
static class FilterSpinnerAdapter extends SettingsSpinnerAdapter<CharSequence> {
private final ManageApplications mManageApplications;
diff --git a/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java b/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java
index f80b01f..7f3bc87 100644
--- a/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java
+++ b/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java
@@ -203,11 +203,15 @@
getMoreButtonTextRes(), this::onNextButtonClick);
requireScrollMixin.setOnRequireScrollStateChangedListener(
scrollNeeded -> {
- // Update text of primary button from "More" to "Agree".
- final int primaryButtonTextRes = scrollNeeded
- ? getMoreButtonTextRes()
- : getAgreeButtonTextRes();
- getPrimaryFooterButton().setText(this, primaryButtonTextRes);
+
+ boolean enrollmentCompleted = checkMaxEnrolled() != 0;
+ if (!enrollmentCompleted) {
+ // Update text of primary button from "More" to "Agree".
+ final int primaryButtonTextRes = scrollNeeded
+ ? getMoreButtonTextRes()
+ : getAgreeButtonTextRes();
+ getPrimaryFooterButton().setText(this, primaryButtonTextRes);
+ }
// Show secondary button once scroll is completed.
if (!scrollNeeded) {
diff --git a/src/com/android/settings/biometrics/BiometricUtils.java b/src/com/android/settings/biometrics/BiometricUtils.java
index 7dd6385..5ee7880 100644
--- a/src/com/android/settings/biometrics/BiometricUtils.java
+++ b/src/com/android/settings/biometrics/BiometricUtils.java
@@ -22,6 +22,9 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
+import android.hardware.biometrics.SensorProperties;
+import android.hardware.face.FaceManager;
+import android.hardware.face.FaceSensorPropertiesInternal;
import android.os.storage.StorageManager;
import android.util.Log;
import android.view.Surface;
@@ -273,4 +276,17 @@
public static boolean isReverseLandscape(@NonNull Context context) {
return context.getDisplay().getRotation() == Surface.ROTATION_270;
}
+
+ /**
+ * @param faceManager
+ * @return True if at least one sensor is set as a convenience.
+ */
+ public static boolean isConvenience(@NonNull FaceManager faceManager) {
+ for (FaceSensorPropertiesInternal props : faceManager.getSensorPropertiesInternal()) {
+ if (props.sensorStrength == SensorProperties.STRENGTH_CONVENIENCE) {
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/src/com/android/settings/biometrics/OWNERS b/src/com/android/settings/biometrics/OWNERS
index 23eaf7e..99dd654 100644
--- a/src/com/android/settings/biometrics/OWNERS
+++ b/src/com/android/settings/biometrics/OWNERS
@@ -1,5 +1,6 @@
# Default reviewers for this and subdirectories.
curtislb@google.com
+graciecheng@google.com
ilyamaty@google.com
jaggies@google.com
jbolinger@google.com
diff --git a/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java b/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java
index 74ea27b..eadb5b8 100644
--- a/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java
+++ b/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java
@@ -19,10 +19,12 @@
import android.app.admin.DevicePolicyManager;
import android.app.settings.SettingsEnums;
import android.content.Intent;
+import android.hardware.SensorPrivacyManager;
import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.face.FaceManager;
import android.hardware.face.FaceSensorPropertiesInternal;
import android.os.Bundle;
+import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
@@ -34,10 +36,12 @@
import com.android.settings.R;
import com.android.settings.Utils;
+import com.android.settings.biometrics.BiometricEnrollActivity;
import com.android.settings.biometrics.BiometricEnrollIntroduction;
import com.android.settings.biometrics.BiometricUtils;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.password.ChooseLockSettingsHelper;
+import com.android.settings.utils.SensorPrivacyManagerHelper;
import com.android.settingslib.RestrictedLockUtilsInternal;
import com.google.android.setupcompat.template.FooterButton;
@@ -57,6 +61,7 @@
private FaceFeatureProvider mFaceFeatureProvider;
@Nullable private FooterButton mPrimaryFooterButton;
@Nullable private FooterButton mSecondaryFooterButton;
+ @Nullable private SensorPrivacyManager mSensorPrivacyManager;
@Override
protected void onCancelButtonClick(View view) {
@@ -150,6 +155,14 @@
});
}
}
+
+ mSensorPrivacyManager = getApplicationContext()
+ .getSystemService(SensorPrivacyManager.class);
+ final SensorPrivacyManagerHelper helper = SensorPrivacyManagerHelper
+ .getInstance(getApplicationContext());
+ final boolean cameraPrivacyEnabled = helper
+ .isSensorBlocked(SensorPrivacyManager.Sensors.CAMERA, mUserId);
+ Log.v(TAG, "cameraPrivacyEnabled : " + cameraPrivacyEnabled);
}
protected boolean generateChallengeOnCreate() {
@@ -309,6 +322,28 @@
}
@Override
+ protected void onNextButtonClick(View view) {
+ final boolean parentelConsentRequired =
+ getIntent()
+ .getBooleanExtra(BiometricEnrollActivity.EXTRA_REQUIRE_PARENTAL_CONSENT, false);
+ final boolean cameraPrivacyEnabled = SensorPrivacyManagerHelper
+ .getInstance(getApplicationContext())
+ .isSensorBlocked(SensorPrivacyManager.Sensors.CAMERA, mUserId);
+ final boolean isSetupWizard = WizardManagerHelper.isAnySetupWizard(getIntent());
+ final boolean isSettingUp = isSetupWizard || (parentelConsentRequired
+ && !WizardManagerHelper.isUserSetupComplete(this));
+ if (cameraPrivacyEnabled && !isSettingUp) {
+ if (mSensorPrivacyManager == null) {
+ mSensorPrivacyManager = getApplicationContext()
+ .getSystemService(SensorPrivacyManager.class);
+ }
+ mSensorPrivacyManager.showSensorUseDialog(SensorPrivacyManager.Sensors.CAMERA);
+ } else {
+ super.onNextButtonClick(view);
+ }
+ }
+
+ @Override
@NonNull
protected FooterButton getPrimaryFooterButton() {
if (mPrimaryFooterButton == null) {
diff --git a/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java b/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java
index d8ff482..616b736 100644
--- a/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java
+++ b/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java
@@ -33,6 +33,7 @@
import com.android.settings.R;
import com.android.settings.SettingsActivity;
+import com.android.settings.biometrics.BiometricUtils;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settings.overlay.FeatureFactory;
@@ -56,6 +57,7 @@
public static class ConfirmRemoveDialog extends InstrumentedDialogFragment {
+ private boolean mIsConvenience;
private DialogInterface.OnClickListener mOnClickListener;
@Override
@@ -68,7 +70,9 @@
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(R.string.security_settings_face_settings_remove_dialog_title)
- .setMessage(R.string.security_settings_face_settings_remove_dialog_details)
+ .setMessage(mIsConvenience
+ ? R.string.security_settings_face_settings_remove_dialog_details_convenience
+ : R.string.security_settings_face_settings_remove_dialog_details)
.setPositiveButton(R.string.delete, mOnClickListener)
.setNegativeButton(R.string.cancel, mOnClickListener);
AlertDialog dialog = builder.create();
@@ -76,6 +80,10 @@
return dialog;
}
+ public void setIsConvenience(boolean isConvenience) {
+ mIsConvenience = isConvenience;
+ }
+
public void setOnClickListener(DialogInterface.OnClickListener listener) {
mOnClickListener = listener;
}
@@ -197,6 +205,7 @@
mRemoving = true;
ConfirmRemoveDialog dialog = new ConfirmRemoveDialog();
dialog.setOnClickListener(mOnClickListener);
+ dialog.setIsConvenience(BiometricUtils.isConvenience(mFaceManager));
dialog.show(mActivity.getSupportFragmentManager(), ConfirmRemoveDialog.class.getName());
}
}
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index f8efcee..87e176e 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -68,6 +68,7 @@
import com.android.settings.biometrics.face.FaceSettings;
import com.android.settings.biometrics.fingerprint.FingerprintSettings;
import com.android.settings.bluetooth.BluetoothDeviceDetailsFragment;
+import com.android.settings.bluetooth.BluetoothPairingDetail;
import com.android.settings.bugreporthandler.BugReportHandlerPicker;
import com.android.settings.connecteddevice.AdvancedConnectedDeviceDashboardFragment;
import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment;
@@ -122,6 +123,7 @@
import com.android.settings.network.NetworkProviderSettings;
import com.android.settings.network.apn.ApnEditor;
import com.android.settings.network.apn.ApnSettings;
+import com.android.settings.network.telephony.NetworkSelectSettings;
import com.android.settings.nfc.AndroidBeam;
import com.android.settings.nfc.PaymentSettings;
import com.android.settings.notification.ConfigureNotificationSettings;
@@ -178,6 +180,7 @@
public static final String[] ENTRY_FRAGMENTS = {
AdvancedConnectedDeviceDashboardFragment.class.getName(),
CreateShortcut.class.getName(),
+ BluetoothPairingDetail.class.getName(),
WifiSettings.class.getName(),
WifiNetworkDetailsFragment.class.getName(),
ConfigureWifiSettings.class.getName(),
@@ -322,6 +325,7 @@
InteractAcrossProfilesDetails.class.getName(),
MediaControlsSettings.class.getName(),
NetworkProviderSettings.class.getName(),
+ NetworkSelectSettings.class.getName(),
AlarmsAndRemindersDetails.class.getName(),
MediaManagementAppsDetails.class.getName(),
AutoBrightnessSettings.class.getName(),
@@ -347,6 +351,7 @@
Settings.WifiSettingsActivity.class.getName(),
Settings.DataUsageSummaryActivity.class.getName(),
Settings.NetworkProviderSettingsActivity.class.getName(),
+ Settings.NetworkSelectActivity.class.getName(),
// Home page > Connected devices
Settings.BluetoothSettingsActivity.class.getName(),
Settings.WifiDisplaySettingsActivity.class.getName(),
diff --git a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
index 91d703d..cdac3b9 100644
--- a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
+++ b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
@@ -36,7 +36,6 @@
import android.app.settings.SettingsEnums;
import android.content.ComponentName;
import android.content.Context;
-import android.content.DialogInterface.OnCancelListener;
import android.content.IContentProvider;
import android.content.Intent;
import android.content.pm.PackageManager;
@@ -63,6 +62,7 @@
import com.android.settings.activityembedding.ActivityEmbeddingRulesController;
import com.android.settings.activityembedding.ActivityEmbeddingUtils;
import com.android.settings.dashboard.profileselector.ProfileSelectDialog;
+import com.android.settings.homepage.TopLevelHighlightMixin;
import com.android.settings.homepage.TopLevelSettings;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.PrimarySwitchPreference;
@@ -170,27 +170,23 @@
if (action != null) {
intent.setAction(action);
}
+ // Register the rule for injected apps.
+ ActivityEmbeddingRulesController.registerTwoPanePairRuleForSettingsHome(
+ mContext,
+ new ComponentName(tile.getPackageName(), tile.getComponentName()),
+ action,
+ true /* clearTop */);
pref.setOnPreferenceClickListener(preference -> {
- OnCancelListener listener = null;
+ TopLevelHighlightMixin highlightMixin = null;
if (fragment instanceof TopLevelSettings
&& ActivityEmbeddingUtils.isEmbeddingActivityEnabled(mContext)) {
- // Register the rule for injected apps.
- ActivityEmbeddingRulesController.registerTwoPanePairRuleForSettingsHome(
- mContext,
- new ComponentName(tile.getPackageName(), tile.getComponentName()),
- null /* secondaryIntentAction */,
- true /* clearTop */);
-
- // Highlight preference ui.
+ // Highlight the preference whenever it's clicked
final TopLevelSettings topLevelSettings = (TopLevelSettings) fragment;
- // Highlight the tile immediately whenever it's clicked
topLevelSettings.setHighlightPreferenceKey(key);
- // If the tile allows users to select profile, the pop-op dialog may be
- // cancelled and then the previous highlight entry should be restored.
- listener = dialog -> topLevelSettings.restorePreviousHighlight();
+ highlightMixin = topLevelSettings.getHighlightMixin();
}
launchIntentOrSelectProfile(activity, tile, intent, sourceMetricsCategory,
- listener);
+ highlightMixin);
return true;
});
}
@@ -223,7 +219,7 @@
SettingsEnums.DASHBOARD_SUMMARY)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
launchIntentOrSelectProfile(activity, tile, intent, SettingsEnums.DASHBOARD_SUMMARY,
- /* listener= */ null);
+ /* highlightMixin= */ null);
}
private DynamicDataObserver createDynamicDataObserver(String method, Uri uri, Preference pref) {
@@ -438,7 +434,7 @@
}
private void launchIntentOrSelectProfile(FragmentActivity activity, Tile tile, Intent intent,
- int sourceMetricCategory, OnCancelListener listener) {
+ int sourceMetricCategory, TopLevelHighlightMixin highlightMixin) {
if (!isIntentResolvable(intent)) {
Log.w(TAG, "Cannot resolve intent, skipping. " + intent);
return;
@@ -469,7 +465,9 @@
}
ProfileSelectDialog.show(activity.getSupportFragmentManager(), tile,
- sourceMetricCategory, listener);
+ sourceMetricCategory, /* onShowListener= */ highlightMixin,
+ /* onDismissListener= */ highlightMixin,
+ /* onCancelListener= */ highlightMixin);
}
}
diff --git a/src/com/android/settings/dashboard/profileselector/ProfileFragmentBridge.java b/src/com/android/settings/dashboard/profileselector/ProfileFragmentBridge.java
index 402982f..2bcc02e 100644
--- a/src/com/android/settings/dashboard/profileselector/ProfileFragmentBridge.java
+++ b/src/com/android/settings/dashboard/profileselector/ProfileFragmentBridge.java
@@ -21,6 +21,7 @@
import com.android.settings.accounts.AccountDashboardFragment;
import com.android.settings.applications.manageapplications.ManageApplications;
import com.android.settings.deviceinfo.StorageDashboardFragment;
+import com.android.settings.inputmethod.AvailableVirtualKeyboardFragment;
import com.android.settings.location.LocationServices;
import java.util.Map;
@@ -46,5 +47,7 @@
ProfileSelectLocationServicesFragment.class.getName());
FRAGMENT_MAP.put(StorageDashboardFragment.class.getName(),
ProfileSelectStorageFragment.class.getName());
+ FRAGMENT_MAP.put(AvailableVirtualKeyboardFragment.class.getName(),
+ ProfileSelectKeyboardFragment.class.getName());
}
}
diff --git a/src/com/android/settings/dashboard/profileselector/ProfileSelectAccountFragment.java b/src/com/android/settings/dashboard/profileselector/ProfileSelectAccountFragment.java
index ac67b58..cf91031 100644
--- a/src/com/android/settings/dashboard/profileselector/ProfileSelectAccountFragment.java
+++ b/src/com/android/settings/dashboard/profileselector/ProfileSelectAccountFragment.java
@@ -17,6 +17,7 @@
package com.android.settings.dashboard.profileselector;
import androidx.fragment.app.Fragment;
+import com.android.settings.R;
import com.android.settings.accounts.AccountPersonalDashboardFragment;
import com.android.settings.accounts.AccountWorkProfileDashboardFragment;
@@ -32,4 +33,9 @@
new AccountWorkProfileDashboardFragment()
};
}
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.accounts_dashboard_settings_header;
+ }
}
diff --git a/src/com/android/settings/dashboard/profileselector/ProfileSelectDialog.java b/src/com/android/settings/dashboard/profileselector/ProfileSelectDialog.java
index b05f23b..e0ba378 100644
--- a/src/com/android/settings/dashboard/profileselector/ProfileSelectDialog.java
+++ b/src/com/android/settings/dashboard/profileselector/ProfileSelectDialog.java
@@ -21,6 +21,8 @@
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.DialogInterface.OnClickListener;
+import android.content.DialogInterface.OnDismissListener;
+import android.content.DialogInterface.OnShowListener;
import android.content.Intent;
import android.os.Bundle;
import android.os.UserHandle;
@@ -45,23 +47,30 @@
private int mSourceMetricCategory;
private Tile mSelectedTile;
+ private OnShowListener mOnShowListener;
private OnCancelListener mOnCancelListener;
+ private OnDismissListener mOnDismissListener;
/**
* Display the profile select dialog, adding the fragment to the given FragmentManager.
* @param manager The FragmentManager this fragment will be added to.
* @param tile The tile for this fragment.
* @param sourceMetricCategory The source metric category.
- * @param listener The listener listens to the dialog cancelling event.
+ * @param onShowListener The listener listens to the dialog showing event.
+ * @param onDismissListener The listener listens to the dialog dismissing event.
+ * @param onCancelListener The listener listens to the dialog cancelling event.
*/
public static void show(FragmentManager manager, Tile tile, int sourceMetricCategory,
- OnCancelListener listener) {
+ OnShowListener onShowListener, OnDismissListener onDismissListener,
+ OnCancelListener onCancelListener) {
final ProfileSelectDialog dialog = new ProfileSelectDialog();
final Bundle args = new Bundle();
args.putParcelable(ARG_SELECTED_TILE, tile);
args.putInt(ARG_SOURCE_METRIC_CATEGORY, sourceMetricCategory);
dialog.setArguments(args);
- dialog.mOnCancelListener = listener;
+ dialog.mOnShowListener = onShowListener;
+ dialog.mOnDismissListener = onDismissListener;
+ dialog.mOnCancelListener = onCancelListener;
dialog.show(manager, "select_profile");
}
@@ -97,12 +106,30 @@
}
@Override
+ public void onStart() {
+ super.onStart();
+ // The fragment shows the dialog within onStart()
+ if (mOnShowListener != null) {
+ mOnShowListener.onShow(getDialog());
+ }
+ }
+
+ @Override
public void onCancel(DialogInterface dialog) {
+ super.onCancel(dialog);
if (mOnCancelListener != null) {
mOnCancelListener.onCancel(dialog);
}
}
+ @Override
+ public void onDismiss(DialogInterface dialog) {
+ super.onDismiss(dialog);
+ if (mOnDismissListener != null) {
+ mOnDismissListener.onDismiss(dialog);
+ }
+ }
+
public static void updateUserHandlesIfNeeded(Context context, Tile tile) {
final List<UserHandle> userHandles = tile.userHandle;
if (tile.userHandle == null || tile.userHandle.size() <= 1) {
diff --git a/src/com/android/settings/dashboard/profileselector/ProfileSelectFragment.java b/src/com/android/settings/dashboard/profileselector/ProfileSelectFragment.java
index 82d524d..3b64d3d 100644
--- a/src/com/android/settings/dashboard/profileselector/ProfileSelectFragment.java
+++ b/src/com/android/settings/dashboard/profileselector/ProfileSelectFragment.java
@@ -107,6 +107,10 @@
Bundle savedInstanceState) {
mContentView = (ViewGroup) super.onCreateView(inflater, container, savedInstanceState);
final Activity activity = getActivity();
+ final int titleResId = getTitleResId();
+ if (titleResId > 0) {
+ activity.setTitle(titleResId);
+ }
final int selectedTab = convertPosition(getTabId(activity, getArguments()));
final View tabContainer = mContentView.findViewById(R.id.tab_container);
@@ -166,6 +170,14 @@
*/
public abstract Fragment[] getFragments();
+ /**
+ * Returns a resource ID of the title
+ * Override this if the title needs to be updated dynamically.
+ */
+ public int getTitleResId() {
+ return 0;
+ }
+
@Override
protected int getPreferenceScreenResId() {
return R.xml.placeholder_preference_screen;
diff --git a/src/com/android/settings/dashboard/profileselector/ProfileSelectKeyboardFragment.java b/src/com/android/settings/dashboard/profileselector/ProfileSelectKeyboardFragment.java
new file mode 100644
index 0000000..c4386e6
--- /dev/null
+++ b/src/com/android/settings/dashboard/profileselector/ProfileSelectKeyboardFragment.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package com.android.settings.dashboard.profileselector;
+
+import android.os.Bundle;
+
+import androidx.fragment.app.Fragment;
+
+import com.android.settings.R;
+import com.android.settings.inputmethod.AvailableVirtualKeyboardFragment;
+
+/**
+ * When current user has work profile, this fragment used following fragments to represent the
+ * on-screen keyboard settings page.
+ *
+ * <p>{@link AvailableVirtualKeyboardFragment} used to show both of personal/work user installed
+ * IMEs.</p>
+ */
+public final class ProfileSelectKeyboardFragment extends ProfileSelectFragment {
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.available_virtual_keyboard;
+ }
+
+ @Override
+ public Fragment[] getFragments() {
+ final Bundle personalOnly = new Bundle();
+ personalOnly.putInt(EXTRA_PROFILE, ProfileType.PERSONAL);
+ final Fragment personalFragment = new AvailableVirtualKeyboardFragment();
+ personalFragment.setArguments(personalOnly);
+
+ final Bundle workOnly = new Bundle();
+ workOnly.putInt(EXTRA_PROFILE, ProfileType.WORK);
+ final Fragment workFragment = new AvailableVirtualKeyboardFragment();
+ workFragment.setArguments(workOnly);
+
+ return new Fragment[]{
+ personalFragment,
+ workFragment
+ };
+ }
+}
diff --git a/src/com/android/settings/dashboard/profileselector/ProfileSelectLocationFragment.java b/src/com/android/settings/dashboard/profileselector/ProfileSelectLocationFragment.java
index e4cde8e..28fb97b 100644
--- a/src/com/android/settings/dashboard/profileselector/ProfileSelectLocationFragment.java
+++ b/src/com/android/settings/dashboard/profileselector/ProfileSelectLocationFragment.java
@@ -60,4 +60,9 @@
workFragment
};
}
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.location_settings_header;
+ }
}
diff --git a/src/com/android/settings/dashboard/profileselector/ProfileSelectLocationServicesFragment.java b/src/com/android/settings/dashboard/profileselector/ProfileSelectLocationServicesFragment.java
index b6f03d6..5f25f59 100644
--- a/src/com/android/settings/dashboard/profileselector/ProfileSelectLocationServicesFragment.java
+++ b/src/com/android/settings/dashboard/profileselector/ProfileSelectLocationServicesFragment.java
@@ -20,6 +20,7 @@
import androidx.fragment.app.Fragment;
+import com.android.settings.R;
import com.android.settings.location.LocationServices;
import com.android.settings.location.LocationServicesForWork;
@@ -44,4 +45,9 @@
workFragment
};
}
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.location_services_header;
+ }
}
diff --git a/src/com/android/settings/dashboard/profileselector/ProfileSelectManageApplications.java b/src/com/android/settings/dashboard/profileselector/ProfileSelectManageApplications.java
index 17fed11..36aa9c5 100644
--- a/src/com/android/settings/dashboard/profileselector/ProfileSelectManageApplications.java
+++ b/src/com/android/settings/dashboard/profileselector/ProfileSelectManageApplications.java
@@ -16,6 +16,8 @@
package com.android.settings.dashboard.profileselector;
+import android.app.Activity;
+import android.content.Intent;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
@@ -43,4 +45,12 @@
workFragment
};
}
+
+ @Override
+ public int getTitleResId() {
+ final Activity activity = getActivity();
+ final Intent intent = activity.getIntent();
+ final Bundle args = getArguments();
+ return ManageApplications.getTitleResId(intent, args);
+ }
}
diff --git a/src/com/android/settings/dashboard/profileselector/ProfileSelectRecentLocationRequestFragment.java b/src/com/android/settings/dashboard/profileselector/ProfileSelectRecentLocationRequestFragment.java
index 058ffe4..16cb43c 100644
--- a/src/com/android/settings/dashboard/profileselector/ProfileSelectRecentLocationRequestFragment.java
+++ b/src/com/android/settings/dashboard/profileselector/ProfileSelectRecentLocationRequestFragment.java
@@ -20,6 +20,7 @@
import androidx.fragment.app.Fragment;
+import com.android.settings.R;
import com.android.settings.location.RecentLocationRequestSeeAllFragment;
/**
@@ -43,4 +44,9 @@
workFragment
};
}
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.location_recent_requests_header;
+ }
}
diff --git a/src/com/android/settings/development/BluetoothA2dpConfigStore.java b/src/com/android/settings/development/BluetoothA2dpConfigStore.java
index 0b154d2..7fd7b13 100644
--- a/src/com/android/settings/development/BluetoothA2dpConfigStore.java
+++ b/src/com/android/settings/development/BluetoothA2dpConfigStore.java
@@ -71,10 +71,16 @@
}
public BluetoothCodecConfig createCodecConfig() {
- return new BluetoothCodecConfig(mCodecType, mCodecPriority,
- mSampleRate, mBitsPerSample,
- mChannelMode, mCodecSpecific1Value,
- mCodecSpecific2Value, mCodecSpecific3Value,
- mCodecSpecific4Value);
+ return new BluetoothCodecConfig.Builder()
+ .setCodecType(mCodecType)
+ .setCodecPriority(mCodecPriority)
+ .setSampleRate(mSampleRate)
+ .setBitsPerSample(mBitsPerSample)
+ .setChannelMode(mChannelMode)
+ .setCodecSpecific1(mCodecSpecific1Value)
+ .setCodecSpecific2(mCodecSpecific2Value)
+ .setCodecSpecific3(mCodecSpecific3Value)
+ .setCodecSpecific4(mCodecSpecific4Value)
+ .build();
}
}
diff --git a/src/com/android/settings/development/bluetooth/AbstractBluetoothDialogPreferenceController.java b/src/com/android/settings/development/bluetooth/AbstractBluetoothDialogPreferenceController.java
index 765c5f8..1af6e96 100644
--- a/src/com/android/settings/development/bluetooth/AbstractBluetoothDialogPreferenceController.java
+++ b/src/com/android/settings/development/bluetooth/AbstractBluetoothDialogPreferenceController.java
@@ -30,6 +30,8 @@
import com.android.settings.development.BluetoothA2dpConfigStore;
import com.android.settingslib.core.lifecycle.Lifecycle;
+import java.util.List;
+
/**
* Abstract class for Bluetooth A2DP config dialog controller in developer option.
*/
@@ -170,7 +172,7 @@
*
* @return Array of {@link BluetoothCodecConfig}.
*/
- protected BluetoothCodecConfig[] getSelectableConfigs(BluetoothDevice device) {
+ protected List<BluetoothCodecConfig> getSelectableConfigs(BluetoothDevice device) {
final BluetoothA2dp bluetoothA2dp = mBluetoothA2dp;
if (bluetoothA2dp == null) {
return null;
@@ -198,11 +200,7 @@
Log.d(TAG, "Unable to get selectable config. No active device.");
return null;
}
- final BluetoothCodecConfig[] configs = getSelectableConfigs(activeDevice);
- if (configs == null) {
- Log.d(TAG, "Unable to get selectable config. Selectable configs is empty.");
- return null;
- }
+ final List<BluetoothCodecConfig> configs = getSelectableConfigs(activeDevice);
for (BluetoothCodecConfig config : configs) {
if (config.getCodecType() == codecTypeValue) {
return config;
@@ -220,7 +218,7 @@
public void onHDAudioEnabled(boolean enabled) {}
static int getHighestCodec(BluetoothA2dp bluetoothA2dp, BluetoothDevice activeDevice,
- BluetoothCodecConfig[] configs) {
+ List<BluetoothCodecConfig> configs) {
if (configs == null) {
Log.d(TAG, "Unable to get highest codec. Configs are empty");
return BluetoothCodecConfig.SOURCE_CODEC_TYPE_INVALID;
@@ -231,8 +229,8 @@
return BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC;
}
for (int i = 0; i < CODEC_TYPES.length; i++) {
- for (int j = 0; j < configs.length; j++) {
- if ((configs[j].getCodecType() == CODEC_TYPES[i])) {
+ for (BluetoothCodecConfig config : configs) {
+ if (config.getCodecType() == CODEC_TYPES[i]) {
return CODEC_TYPES[i];
}
}
diff --git a/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceController.java b/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceController.java
index b1b58e5..5f916f3 100644
--- a/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceController.java
+++ b/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceController.java
@@ -77,7 +77,7 @@
// Check HD audio is enabled, display the available list.
if (bluetoothA2dp.isOptionalCodecsEnabled(activeDevice)
== BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED) {
- BluetoothCodecConfig[] configs = getSelectableConfigs(activeDevice);
+ List<BluetoothCodecConfig> configs = getSelectableConfigs(activeDevice);
if (configs != null) {
return getIndexFromConfig(configs);
}
@@ -153,10 +153,10 @@
writeConfigurationValues(/* index= */ 0);
}
- private List<Integer> getIndexFromConfig(BluetoothCodecConfig[] configs) {
+ private List<Integer> getIndexFromConfig(List<BluetoothCodecConfig> configs) {
List<Integer> indexArray = new ArrayList<>();
- for (int i = 0; i < configs.length; i++) {
- indexArray.add(convertCfgToBtnIndex(configs[i].getCodecType()));
+ for (BluetoothCodecConfig config : configs) {
+ indexArray.add(convertCfgToBtnIndex(config.getCodecType()));
}
return indexArray;
}
diff --git a/src/com/android/settings/deviceinfo/PhoneNumberPreferenceController.java b/src/com/android/settings/deviceinfo/PhoneNumberPreferenceController.java
index 6c32c59..d196af7 100644
--- a/src/com/android/settings/deviceinfo/PhoneNumberPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/PhoneNumberPreferenceController.java
@@ -159,6 +159,6 @@
@VisibleForTesting
protected Preference createNewPreference(Context context) {
- return new Preference(context);
+ return new PhoneNumberSummaryPreference(context);
}
}
diff --git a/src/com/android/settings/deviceinfo/PhoneNumberSummaryPreference.java b/src/com/android/settings/deviceinfo/PhoneNumberSummaryPreference.java
new file mode 100644
index 0000000..2e31084
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/PhoneNumberSummaryPreference.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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.
+ */
+package com.android.settings.deviceinfo;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.TextView;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceViewHolder;
+
+/**
+ * Preference which support phone number talkback in summary part.
+ */
+public class PhoneNumberSummaryPreference extends Preference {
+
+ /**
+ * Constructor
+ * @param context
+ */
+ public PhoneNumberSummaryPreference(Context context) {
+ this(context, null);
+ }
+
+ /**
+ * Constructor
+ * @param context
+ * @param attrs
+ */
+ public PhoneNumberSummaryPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder holder) {
+ super.onBindViewHolder(holder);
+
+ // Expand text to support phone number talkback.
+ TextView summaryView = (TextView) holder.findViewById(android.R.id.summary);
+ if (summaryView != null) {
+ summaryView.setText(PhoneNumberUtil.expandByTts(summaryView.getText()));
+ }
+ }
+}
diff --git a/src/com/android/settings/deviceinfo/PhoneNumberUtil.java b/src/com/android/settings/deviceinfo/PhoneNumberUtil.java
new file mode 100644
index 0000000..77e02b4
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/PhoneNumberUtil.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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.
+ */
+package com.android.settings.deviceinfo;
+
+import android.text.Spannable;
+import android.text.SpannableStringBuilder;
+import android.text.Spanned;
+import android.text.TextUtils;
+import android.text.style.TtsSpan;
+
+import java.util.Arrays;
+import java.util.stream.IntStream;
+
+/**
+ * Helper class to detect format of phone number.
+ */
+public class PhoneNumberUtil {
+
+ /**
+ * Convert given text to support phone number talkback.
+ * @param text given
+ * @return converted text
+ */
+ public static CharSequence expandByTts(CharSequence text) {
+ if ((text == null) || (text.length() <= 0)
+ || (!isPhoneNumberDigits(text))) {
+ return text;
+ }
+ Spannable spannable = new SpannableStringBuilder(text);
+ TtsSpan span = new TtsSpan.DigitsBuilder(text.toString()).build();
+ spannable.setSpan(span, 0, spannable.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ return spannable;
+ }
+
+ /**
+ * Check if given text may contains a phone id related numbers.
+ * (ex: phone number, IMEI, ICCID)
+ * @param text given
+ * @return true when given text is a phone id related number.
+ */
+ private static boolean isPhoneNumberDigits(CharSequence text) {
+ long textLength = (long)text.length();
+ return (textLength == text.chars()
+ .filter(c -> isPhoneNumberDigit(c)).count());
+ }
+
+ private static boolean isPhoneNumberDigit(int c) {
+ return ((c >= (int)'0') && (c <= (int)'9'))
+ || (c == (int)'-') || (c == (int)'+')
+ || (c == (int)'(') || (c == (int)')');
+ }
+}
diff --git a/src/com/android/settings/deviceinfo/imei/ImeiInfoDialogController.java b/src/com/android/settings/deviceinfo/imei/ImeiInfoDialogController.java
index a10b9f1..1ae6b40 100644
--- a/src/com/android/settings/deviceinfo/imei/ImeiInfoDialogController.java
+++ b/src/com/android/settings/deviceinfo/imei/ImeiInfoDialogController.java
@@ -21,11 +21,6 @@
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
-import android.text.Spannable;
-import android.text.SpannableStringBuilder;
-import android.text.Spanned;
-import android.text.TextUtils;
-import android.text.style.TtsSpan;
import android.util.Log;
import androidx.annotation.NonNull;
@@ -53,19 +48,6 @@
@VisibleForTesting
static final int ID_GSM_SETTINGS = R.id.gsm_settings;
- private static CharSequence getTextAsDigits(CharSequence text) {
- if (TextUtils.isEmpty(text)) {
- return "";
- }
- if (TextUtils.isDigitsOnly(text)) {
- final Spannable spannable = new SpannableStringBuilder(text);
- final TtsSpan span = new TtsSpan.DigitsBuilder(text.toString()).build();
- spannable.setSpan(span, 0, spannable.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
- text = spannable;
- }
- return text;
- }
-
private final ImeiInfoDialogFragment mDialog;
private final TelephonyManager mTelephonyManager;
private final SubscriptionInfo mSubscriptionInfo;
@@ -121,10 +103,9 @@
if ((mSubscriptionInfo != null && isCdmaLteEnabled()) ||
(mSubscriptionInfo == null && isSimPresent(mSlotId))) {
// Show IMEI for LTE device
- mDialog.setText(ID_IMEI_VALUE,
- getTextAsDigits(mTelephonyManager.getImei(mSlotId)));
+ mDialog.setText(ID_IMEI_VALUE, mTelephonyManager.getImei(mSlotId));
mDialog.setText(ID_IMEI_SV_VALUE,
- getTextAsDigits(mTelephonyManager.getDeviceSoftwareVersion(mSlotId)));
+ mTelephonyManager.getDeviceSoftwareVersion(mSlotId));
} else {
// device is not GSM/UMTS, do not display GSM/UMTS features
mDialog.removeViewFromScreen(ID_GSM_SETTINGS);
@@ -132,9 +113,9 @@
}
private void updateDialogForGsmPhone() {
- mDialog.setText(ID_IMEI_VALUE, getTextAsDigits(mTelephonyManager.getImei(mSlotId)));
+ mDialog.setText(ID_IMEI_VALUE, mTelephonyManager.getImei(mSlotId));
mDialog.setText(ID_IMEI_SV_VALUE,
- getTextAsDigits(mTelephonyManager.getDeviceSoftwareVersion(mSlotId)));
+ mTelephonyManager.getDeviceSoftwareVersion(mSlotId));
// device is not CDMA, do not display CDMA features
mDialog.removeViewFromScreen(ID_CDMA_SETTINGS);
}
diff --git a/src/com/android/settings/deviceinfo/imei/ImeiInfoDialogFragment.java b/src/com/android/settings/deviceinfo/imei/ImeiInfoDialogFragment.java
index b2f083f..c8d78da 100644
--- a/src/com/android/settings/deviceinfo/imei/ImeiInfoDialogFragment.java
+++ b/src/com/android/settings/deviceinfo/imei/ImeiInfoDialogFragment.java
@@ -31,8 +31,12 @@
import androidx.fragment.app.FragmentManager;
import com.android.settings.R;
+import com.android.settings.deviceinfo.PhoneNumberUtil;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+import java.util.Arrays;
+import java.util.stream.IntStream;
+
public class ImeiInfoDialogFragment extends InstrumentedDialogFragment {
@VisibleForTesting
@@ -83,13 +87,27 @@
}
}
+ /**
+ * View ID(s) which is digit format (instead of decimal number) text.
+ **/
+ private static final int [] sViewIdsInDigitFormat = IntStream
+ .of(ImeiInfoDialogController.ID_MEID_NUMBER_VALUE,
+ ImeiInfoDialogController.ID_MIN_NUMBER_VALUE,
+ ImeiInfoDialogController.ID_IMEI_VALUE,
+ ImeiInfoDialogController.ID_IMEI_SV_VALUE)
+ .sorted().toArray();
+
public void setText(int viewId, CharSequence text) {
final TextView textView = mRootView.findViewById(viewId);
+ if (textView == null) {
+ return;
+ }
if (TextUtils.isEmpty(text)) {
text = getResources().getString(R.string.device_info_default);
}
- if (textView != null) {
- textView.setText(text);
+ else if (Arrays.binarySearch(sViewIdsInDigitFormat, viewId) >= 0) {
+ text = PhoneNumberUtil.expandByTts(text);
}
+ textView.setText(text);
}
}
diff --git a/src/com/android/settings/deviceinfo/imei/ImeiInfoPreferenceController.java b/src/com/android/settings/deviceinfo/imei/ImeiInfoPreferenceController.java
index 407e4e5..e0bff6d 100644
--- a/src/com/android/settings/deviceinfo/imei/ImeiInfoPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/imei/ImeiInfoPreferenceController.java
@@ -32,6 +32,7 @@
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
+import com.android.settings.deviceinfo.PhoneNumberSummaryPreference;
import com.android.settings.slices.Sliceable;
import com.android.settingslib.Utils;
@@ -162,6 +163,6 @@
@VisibleForTesting
Preference createNewPreference(Context context) {
- return new Preference(context);
+ return new PhoneNumberSummaryPreference(context);
}
}
diff --git a/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java b/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java
index f2bce78..2cf523f 100644
--- a/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java
+++ b/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java
@@ -134,7 +134,7 @@
}
if (SubscriptionManager.isValidSubscriptionId(nextSubId)) {
mTelephonyManager =
- mTelephonyManager.createForSubscriptionId(nextSubId);
+ getTelephonyManager().createForSubscriptionId(nextSubId);
registerImsRegistrationCallback(nextSubId);
}
}
@@ -228,6 +228,11 @@
}
}
+ @VisibleForTesting
+ public TelephonyManager getTelephonyManager() {
+ return mTelephonyManager;
+ }
+
public void initialize() {
requestForUpdateEid();
@@ -235,7 +240,7 @@
return;
}
mTelephonyManager =
- mTelephonyManager.createForSubscriptionId(mSubscriptionInfo.getSubscriptionId());
+ getTelephonyManager().createForSubscriptionId(mSubscriptionInfo.getSubscriptionId());
mTelephonyCallback = new SimStatusDialogTelephonyCallback();
updateLatestAreaInfo();
updateSubscriptionStatus();
@@ -246,8 +251,8 @@
// getServiceState() may return null when the subscription is inactive
// or when there was an error communicating with the phone process.
- final ServiceState serviceState = mTelephonyManager.getServiceState();
- final SignalStrength signalStrength = mTelephonyManager.getSignalStrength();
+ final ServiceState serviceState = getTelephonyManager().getServiceState();
+ final SignalStrength signalStrength = getTelephonyManager().getSignalStrength();
updatePhoneNumber();
updateServiceState(serviceState);
@@ -279,9 +284,10 @@
if (mSubscriptionInfo == null) {
return;
}
- mTelephonyManager = mTelephonyManager.createForSubscriptionId(
+ mTelephonyManager = getTelephonyManager().createForSubscriptionId(
mSubscriptionInfo.getSubscriptionId());
- mTelephonyManager.registerTelephonyCallback(mContext.getMainExecutor(), mTelephonyCallback);
+ getTelephonyManager()
+ .registerTelephonyCallback(mContext.getMainExecutor(), mTelephonyCallback);
mSubscriptionManager.addOnSubscriptionsChangedListener(
mContext.getMainExecutor(), mOnSubscriptionsChangedListener);
registerImsRegistrationCallback(mSubscriptionInfo.getSubscriptionId());
@@ -304,7 +310,7 @@
if (mIsRegisteredListener) {
mSubscriptionManager.removeOnSubscriptionsChangedListener(
mOnSubscriptionsChangedListener);
- mTelephonyManager.unregisterTelephonyCallback(mTelephonyCallback);
+ getTelephonyManager().unregisterTelephonyCallback(mTelephonyCallback);
if (mShowLatestAreaInfo) {
mContext.unregisterReceiver(mAreaInfoReceiver);
}
@@ -315,7 +321,7 @@
unregisterImsRegistrationCallback(mSubscriptionInfo.getSubscriptionId());
mSubscriptionManager.removeOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
- mTelephonyManager.unregisterTelephonyCallback(mTelephonyCallback);
+ getTelephonyManager().unregisterTelephonyCallback(mTelephonyCallback);
if (mShowLatestAreaInfo) {
mContext.unregisterReceiver(mAreaInfoReceiver);
@@ -329,7 +335,7 @@
}
@VisibleForTesting
- protected void updatePhoneNumber() {
+ public void updatePhoneNumber() {
// If formattedNumber is null or empty, it'll display as "Unknown".
mDialog.setText(PHONE_NUMBER_VALUE_ID,
DeviceInfoUtils.getBidiFormattedPhoneNumber(mContext, mSubscriptionInfo));
@@ -433,7 +439,7 @@
private void updateLatestAreaInfo() {
mShowLatestAreaInfo = Resources.getSystem().getBoolean(
com.android.internal.R.bool.config_showAreaUpdateInfoSettings)
- && mTelephonyManager.getPhoneType() != TelephonyManager.PHONE_TYPE_CDMA;
+ && getTelephonyManager().getPhoneType() != TelephonyManager.PHONE_TYPE_CDMA;
if (mShowLatestAreaInfo) {
// Bind cell broadcast service to get the area info. The info will be updated once
@@ -451,7 +457,7 @@
resetSignalStrength();
} else if (!Utils.isInService(mPreviousServiceState)) {
// If ServiceState changed from out of service -> in service, update signal strength.
- updateSignalStrength(mTelephonyManager.getSignalStrength());
+ updateSignalStrength(getTelephonyManager().getSignalStrength());
}
String serviceStateValue;
@@ -498,7 +504,7 @@
return;
}
- ServiceState serviceState = mTelephonyManager.getServiceState();
+ ServiceState serviceState = getTelephonyManager().getServiceState();
if (!Utils.isInService(serviceState)) {
return;
}
@@ -536,8 +542,8 @@
String dataNetworkTypeName = null;
String voiceNetworkTypeName = null;
final int subId = mSubscriptionInfo.getSubscriptionId();
- final int actualDataNetworkType = mTelephonyManager.getDataNetworkType();
- final int actualVoiceNetworkType = mTelephonyManager.getVoiceNetworkType();
+ final int actualDataNetworkType = getTelephonyManager().getDataNetworkType();
+ final int actualVoiceNetworkType = getTelephonyManager().getVoiceNetworkType();
final int overrideNetworkType = mTelephonyDisplayInfo == null
? TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE
: mTelephonyDisplayInfo.getOverrideNetworkType();
@@ -604,7 +610,7 @@
mDialog.removeSettingFromScreen(ICCID_INFO_LABEL_ID);
mDialog.removeSettingFromScreen(ICCID_INFO_VALUE_ID);
} else {
- mDialog.setText(ICCID_INFO_VALUE_ID, mTelephonyManager.getSimSerialNumber());
+ mDialog.setText(ICCID_INFO_VALUE_ID, getTelephonyManager().getSimSerialNumber());
}
}
@@ -617,10 +623,10 @@
}
@VisibleForTesting
- protected AtomicReference<String> getEid(int slotIndex) {
+ public AtomicReference<String> getEid(int slotIndex) {
boolean shouldHaveEid = false;
String eid = null;
- if (mTelephonyManager.getActiveModemCount() > MAX_PHONE_COUNT_SINGLE_SIM) {
+ if (getTelephonyManager().getActiveModemCount() > MAX_PHONE_COUNT_SINGLE_SIM) {
// Get EID per-SIM in multi-SIM mode
final Map<Integer, Integer> mapping = mTelephonyManager
.getLogicalToPhysicalSlotMapping();
@@ -628,7 +634,7 @@
SubscriptionManager.INVALID_SIM_SLOT_INDEX);
if (pSlotId != SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
- final List<UiccCardInfo> infos = mTelephonyManager.getUiccCardsInfo();
+ final List<UiccCardInfo> infos = getTelephonyManager().getUiccCardsInfo();
for (UiccCardInfo info : infos) {
if (info.getPhysicalSlotIndex() == pSlotId) {
diff --git a/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogFragment.java b/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogFragment.java
index 93323b3..8eb71df 100644
--- a/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogFragment.java
+++ b/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogFragment.java
@@ -30,6 +30,10 @@
import com.android.settings.R;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+import com.android.settings.deviceinfo.PhoneNumberUtil;
+
+import java.util.Arrays;
+import java.util.stream.IntStream;
public class SimStatusDialogFragment extends InstrumentedDialogFragment {
@@ -87,13 +91,26 @@
}
}
+ /**
+ * View ID(s) which is digit format (instead of decimal number) text.
+ **/
+ private static final int [] sViewIdsInDigitFormat = IntStream
+ .of(SimStatusDialogController.ICCID_INFO_VALUE_ID,
+ SimStatusDialogController.PHONE_NUMBER_VALUE_ID,
+ SimStatusDialogController.EID_INFO_VALUE_ID)
+ .sorted().toArray();
+
public void setText(int viewId, CharSequence text) {
final TextView textView = mRootView.findViewById(viewId);
+ if (textView == null) {
+ return;
+ }
if (TextUtils.isEmpty(text)) {
text = getResources().getString(R.string.device_info_default);
}
- if (textView != null) {
- textView.setText(text);
+ else if (Arrays.binarySearch(sViewIdsInDigitFormat, viewId) >= 0) {
+ text = PhoneNumberUtil.expandByTts(text);
}
+ textView.setText(text);
}
}
diff --git a/src/com/android/settings/display/FontSizePreferenceFragmentForSetupWizard.java b/src/com/android/settings/display/FontSizePreferenceFragmentForSetupWizard.java
index 627f107..5bfce18 100644
--- a/src/com/android/settings/display/FontSizePreferenceFragmentForSetupWizard.java
+++ b/src/com/android/settings/display/FontSizePreferenceFragmentForSetupWizard.java
@@ -17,6 +17,13 @@
package com.android.settings.display;
import android.app.settings.SettingsEnums;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+
+import androidx.viewpager.widget.ViewPager;
import com.android.settings.R;
@@ -34,6 +41,23 @@
}
@Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ final View root = super.onCreateView(inflater, container, savedInstanceState);
+ if (getResources().getBoolean(R.bool.config_supported_large_screen)) {
+ final ViewPager viewPager = root.findViewById(R.id.preview_pager);
+ final View view = (View) viewPager.getAdapter().instantiateItem(viewPager,
+ viewPager.getCurrentItem());
+ final LinearLayout layout = view.findViewById(R.id.font_size_preview_text_group);
+ final int paddingStart = getResources().getDimensionPixelSize(
+ R.dimen.font_size_preview_padding_start);
+ layout.setPaddingRelative(paddingStart, layout.getPaddingTop(),
+ layout.getPaddingEnd(), layout.getPaddingBottom());
+ }
+ return root;
+ }
+
+ @Override
public void onStop() {
// Log the final choice in value if it's different from the previous value.
if (mCurrentIndex != mInitialIndex) {
diff --git a/src/com/android/settings/display/TopLevelWallpaperPreferenceController.java b/src/com/android/settings/display/TopLevelWallpaperPreferenceController.java
index 7640d08..0136eac 100644
--- a/src/com/android/settings/display/TopLevelWallpaperPreferenceController.java
+++ b/src/com/android/settings/display/TopLevelWallpaperPreferenceController.java
@@ -63,6 +63,11 @@
super.displayPreference(screen);
Preference preference = screen.findPreference(getPreferenceKey());
preference.setTitle(getTitle());
+ ActivityEmbeddingRulesController.registerTwoPanePairRuleForSettingsHome(
+ mContext,
+ getComponentName(),
+ null /* secondaryIntentAction */,
+ true /* clearTop */);
}
public String getTitle() {
@@ -103,11 +108,6 @@
mContext)) {
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
}
- ActivityEmbeddingRulesController.registerTwoPanePairRuleForSettingsHome(
- mContext,
- intent.getComponent(),
- null /* secondaryIntentAction */,
- true /* clearTop */);
preference.getContext().startActivity(intent);
return true;
}
diff --git a/src/com/android/settings/fuelgauge/TopLevelBatteryPreferenceController.java b/src/com/android/settings/fuelgauge/TopLevelBatteryPreferenceController.java
index f86b1ff..7f314d1 100644
--- a/src/com/android/settings/fuelgauge/TopLevelBatteryPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/TopLevelBatteryPreferenceController.java
@@ -18,7 +18,6 @@
import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
@@ -32,8 +31,6 @@
import com.android.settingslib.core.lifecycle.events.OnStop;
import com.android.settingslib.utils.ThreadUtils;
-import java.util.HashMap;
-
public class TopLevelBatteryPreferenceController extends BasePreferenceController implements
LifecycleObserver, OnStart, OnStop, BatteryPreferenceController {
@@ -43,13 +40,9 @@
Preference mPreference;
private final BatteryBroadcastReceiver mBatteryBroadcastReceiver;
private BatteryInfo mBatteryInfo;
- private BatterySettingsFeatureProvider mBatterySettingsFeatureProvider;
private BatteryStatusFeatureProvider mBatteryStatusFeatureProvider;
private String mBatteryStatusLabel;
- @VisibleForTesting
- protected static HashMap<String, ComponentName> sReplacingActivityMap = new HashMap<>();
-
public TopLevelBatteryPreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
mBatteryBroadcastReceiver = new BatteryBroadcastReceiver(mContext);
@@ -63,8 +56,6 @@
}, true /* shortString */);
});
- mBatterySettingsFeatureProvider = FeatureFactory.getFactory(context)
- .getBatterySettingsFeatureProvider(context);
mBatteryStatusFeatureProvider = FeatureFactory.getFactory(context)
.getBatteryStatusFeatureProvider(context);
}
@@ -82,37 +73,6 @@
}
@Override
- public boolean handlePreferenceTreeClick(Preference preference) {
- String prefFrag = preference.getFragment();
- if (prefFrag == null || prefFrag.isEmpty()) {
- // Not a redirect, so use the default.
- return super.handlePreferenceTreeClick(preference);
- }
-
- ComponentName currentFragmentName = convertClassPathToComponentName(prefFrag);
- if (currentFragmentName == null) {
- return super.handlePreferenceTreeClick(preference);
- }
-
- ComponentName replacingActivity;
- if (sReplacingActivityMap.containsKey(prefFrag)) {
- replacingActivity = sReplacingActivityMap.get(prefFrag);
- } else {
- replacingActivity = mBatterySettingsFeatureProvider.getReplacingActivity(
- currentFragmentName);
- sReplacingActivityMap.put(prefFrag, replacingActivity);
- }
-
- if (replacingActivity == null || currentFragmentName.compareTo(replacingActivity) == 0) {
- return super.handlePreferenceTreeClick(preference);
- }
- Intent intent = new Intent();
- intent.setComponent(replacingActivity);
- mContext.startActivity(intent);
- return true;
- }
-
- @Override
public void onStart() {
mBatteryBroadcastReceiver.register();
}
diff --git a/src/com/android/settings/gestures/TapScreenGesturePreferenceController.java b/src/com/android/settings/gestures/TapScreenGesturePreferenceController.java
index 179ed26..86ac713 100644
--- a/src/com/android/settings/gestures/TapScreenGesturePreferenceController.java
+++ b/src/com/android/settings/gestures/TapScreenGesturePreferenceController.java
@@ -21,6 +21,7 @@
import android.annotation.UserIdInt;
import android.content.Context;
import android.hardware.display.AmbientDisplayConfiguration;
+import android.os.SystemProperties;
import android.os.UserHandle;
import android.provider.Settings;
@@ -74,8 +75,10 @@
@Override
public boolean setChecked(boolean isChecked) {
- return Settings.Secure.putInt(mContext.getContentResolver(), DOZE_TAP_SCREEN_GESTURE,
- isChecked ? 1 : 0);
+ boolean success = Settings.Secure.putInt(mContext.getContentResolver(),
+ DOZE_TAP_SCREEN_GESTURE, isChecked ? 1 : 0);
+ SystemProperties.set("persist.sys.tap_gesture", isChecked ? "1" : "0");
+ return success;
}
private AmbientDisplayConfiguration getAmbientConfig() {
diff --git a/src/com/android/settings/homepage/SettingsHomepageActivity.java b/src/com/android/settings/homepage/SettingsHomepageActivity.java
index 31cc7aa..9076053 100644
--- a/src/com/android/settings/homepage/SettingsHomepageActivity.java
+++ b/src/com/android/settings/homepage/SettingsHomepageActivity.java
@@ -76,7 +76,7 @@
public static final String EXTRA_SETTINGS_LARGE_SCREEN_DEEP_LINK_INTENT_DATA =
"settings_large_screen_deep_link_intent_data";
- private static final int DEFAULT_HIGHLIGHT_MENU_KEY = R.string.menu_key_network;
+ static final int DEFAULT_HIGHLIGHT_MENU_KEY = R.string.menu_key_network;
private static final long HOMEPAGE_LOADING_TIMEOUT_MS = 300;
private TopLevelSettings mMainFragment;
@@ -94,6 +94,10 @@
void onHomepageLoaded();
}
+ private interface FragmentBuilder<T extends Fragment> {
+ T build();
+ }
+
/**
* Try to add a {@link HomepageLoadedListener}. If homepage is already loaded, the listener
* will not be notified.
@@ -121,11 +125,8 @@
}
Log.i(TAG, "showHomepageWithSuggestion: " + showSuggestion);
final View homepageView = mHomepageView;
- if (!mIsTwoPaneLastTime) {
- mSuggestionView.setVisibility(showSuggestion ? View.VISIBLE : View.GONE);
- } else {
- mTwoPaneSuggestionView.setVisibility(showSuggestion ? View.VISIBLE : View.GONE);
- }
+ mSuggestionView.setVisibility(showSuggestion ? View.VISIBLE : View.GONE);
+ mTwoPaneSuggestionView.setVisibility(showSuggestion ? View.VISIBLE : View.GONE);
mHomepageView = null;
mLoadedListeners.forEach(listener -> listener.onHomepageLoaded());
@@ -163,18 +164,23 @@
mCategoryMixin = new CategoryMixin(this);
getLifecycle().addObserver(mCategoryMixin);
+ final String highlightMenuKey = getHighlightMenuKey();
// Only allow features on high ram devices.
if (!getSystemService(ActivityManager.class).isLowRamDevice()) {
initAvatarView();
- showSuggestionFragment();
+ final boolean scrollNeeded = mIsEmbeddingActivityEnabled
+ && !TextUtils.equals(getString(DEFAULT_HIGHLIGHT_MENU_KEY), highlightMenuKey);
+ showSuggestionFragment(scrollNeeded);
if (FeatureFlagUtils.isEnabled(this, FeatureFlags.CONTEXTUAL_HOME)) {
- showFragment(new ContextualCardsFragment(), R.id.contextual_cards_content);
+ showFragment(() -> new ContextualCardsFragment(), R.id.contextual_cards_content);
}
}
- mMainFragment = new TopLevelSettings();
- mMainFragment.getArguments().putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY,
- getHighlightMenuKey());
- showFragment(mMainFragment, R.id.main_content);
+ mMainFragment = showFragment(() -> {
+ final TopLevelSettings fragment = new TopLevelSettings();
+ fragment.getArguments().putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY,
+ highlightMenuKey);
+ return fragment;
+ }, R.id.main_content);
((FrameLayout) findViewById(R.id.main_content))
.getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);
@@ -259,43 +265,49 @@
findViewById(R.id.settings_homepage_container).setBackgroundColor(color);
}
- private void showSuggestionFragment() {
- final Class<? extends Fragment> fragment = FeatureFactory.getFactory(this)
+ private void showSuggestionFragment(boolean scrollNeeded) {
+ final Class<? extends Fragment> fragmentClass = FeatureFactory.getFactory(this)
.getSuggestionFeatureProvider(this).getContextualSuggestionFragment();
- if (fragment == null) {
+ if (fragmentClass == null) {
return;
}
mSuggestionView = findViewById(R.id.suggestion_content);
mTwoPaneSuggestionView = findViewById(R.id.two_pane_suggestion_content);
mHomepageView = findViewById(R.id.settings_homepage_container);
- // Hide the homepage for preparing the suggestion.
- mHomepageView.setVisibility(View.INVISIBLE);
+ // Hide the homepage for preparing the suggestion. If scrolling is needed, the list views
+ // should be initialized in the invisible homepage view to prevent a scroll flicker.
+ mHomepageView.setVisibility(scrollNeeded ? View.INVISIBLE : View.GONE);
// Schedule a timer to show the homepage and hide the suggestion on timeout.
mHomepageView.postDelayed(() -> showHomepageWithSuggestion(false),
HOMEPAGE_LOADING_TIMEOUT_MS);
- try {
- showFragment(fragment.getConstructor().newInstance(), R.id.suggestion_content);
- if (mIsEmbeddingActivityEnabled) {
- showFragment(fragment.getConstructor().newInstance(),
- R.id.two_pane_suggestion_content);
+ final FragmentBuilder<?> fragmentBuilder = () -> {
+ try {
+ return fragmentClass.getConstructor().newInstance();
+ } catch (Exception e) {
+ Log.w(TAG, "Cannot show fragment", e);
}
- } catch (Exception e) {
- Log.w(TAG, "Cannot show fragment", e);
+ return null;
+ };
+ showFragment(fragmentBuilder, R.id.suggestion_content);
+ if (mIsEmbeddingActivityEnabled) {
+ showFragment(fragmentBuilder, R.id.two_pane_suggestion_content);
}
}
- private void showFragment(Fragment fragment, int id) {
+ private <T extends Fragment> T showFragment(FragmentBuilder<T> fragmentBuilder, int id) {
final FragmentManager fragmentManager = getSupportFragmentManager();
final FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
- final Fragment showFragment = fragmentManager.findFragmentById(id);
+ T showFragment = (T) fragmentManager.findFragmentById(id);
if (showFragment == null) {
- fragmentTransaction.add(id, fragment);
+ showFragment = fragmentBuilder.build();
+ fragmentTransaction.add(id, showFragment);
} else {
fragmentTransaction.show(showFragment);
}
fragmentTransaction.commit();
+ return showFragment;
}
private void launchDeepLinkIntentToRight() {
@@ -363,14 +375,14 @@
targetIntent.getAction(),
SplitRule.FINISH_ALWAYS,
SplitRule.FINISH_ALWAYS,
- true /* clearTop*/);
+ true /* clearTop */);
ActivityEmbeddingRulesController.registerTwoPanePairRule(this,
- new ComponentName(Settings.class.getPackageName(), Settings.class.getName()),
+ new ComponentName(getApplicationContext(), Settings.class),
targetComponentName,
targetIntent.getAction(),
SplitRule.FINISH_ALWAYS,
SplitRule.FINISH_ALWAYS,
- true /* clearTop*/);
+ true /* clearTop */);
startActivity(targetIntent);
}
diff --git a/src/com/android/settings/homepage/TopLevelHighlightMixin.java b/src/com/android/settings/homepage/TopLevelHighlightMixin.java
new file mode 100644
index 0000000..ebfe7f2
--- /dev/null
+++ b/src/com/android/settings/homepage/TopLevelHighlightMixin.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package com.android.settings.homepage;
+
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+import android.util.Log;
+
+import androidx.fragment.app.FragmentActivity;
+import androidx.preference.PreferenceScreen;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.settings.SettingsActivity;
+import com.android.settings.widget.HighlightableTopLevelPreferenceAdapter;
+
+/** A highlight mixin for the top level settings fragment. */
+public class TopLevelHighlightMixin implements Parcelable, DialogInterface.OnShowListener,
+ DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
+
+ private static final String TAG = "TopLevelHighlightMixin";
+
+ private String mCurrentKey;
+ // Stores the previous key for the profile select dialog cancel event
+ private String mPreviousKey;
+ // Stores the key hidden for the search page presence
+ private String mHiddenKey;
+ private DialogInterface mDialog;
+ private HighlightableTopLevelPreferenceAdapter mTopLevelAdapter;
+
+ public TopLevelHighlightMixin() {
+ }
+
+ public TopLevelHighlightMixin(Parcel source) {
+ mCurrentKey = source.readString();
+ mPreviousKey = source.readString();
+ mHiddenKey = source.readString();
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(mCurrentKey);
+ dest.writeString(mPreviousKey);
+ dest.writeString(mHiddenKey);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ public static final Creator<TopLevelHighlightMixin> CREATOR = new Creator<>() {
+ @Override
+ public TopLevelHighlightMixin createFromParcel(Parcel source) {
+ return new TopLevelHighlightMixin(source);
+ }
+
+ @Override
+ public TopLevelHighlightMixin[] newArray(int size) {
+ return new TopLevelHighlightMixin[size];
+ }
+ };
+
+ @Override
+ public void onShow(DialogInterface dialog) {
+ mDialog = dialog;
+ }
+
+ @Override
+ public void onDismiss(DialogInterface dialog) {
+ mDialog = null;
+ }
+
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ if (mTopLevelAdapter != null) {
+ mCurrentKey = mPreviousKey;
+ mPreviousKey = null;
+ mTopLevelAdapter.highlightPreference(mCurrentKey, /* scrollNeeded= */ false);
+ }
+ }
+
+ RecyclerView.Adapter onCreateAdapter(TopLevelSettings topLevelSettings,
+ PreferenceScreen preferenceScreen) {
+ if (TextUtils.isEmpty(mCurrentKey)) {
+ mCurrentKey = getHighlightPrefKeyFromArguments(topLevelSettings.getArguments());
+ }
+
+ Log.d(TAG, "onCreateAdapter, pref key: " + mCurrentKey);
+ mTopLevelAdapter = new HighlightableTopLevelPreferenceAdapter(
+ (SettingsHomepageActivity) topLevelSettings.getActivity(), preferenceScreen,
+ topLevelSettings.getListView(), mCurrentKey);
+ return mTopLevelAdapter;
+ }
+
+ void reloadHighlightMenuKey(Bundle arguments) {
+ if (mTopLevelAdapter == null) {
+ return;
+ }
+ ensureDialogDismissed();
+
+ mCurrentKey = getHighlightPrefKeyFromArguments(arguments);
+ Log.d(TAG, "reloadHighlightMenuKey, pref key: " + mCurrentKey);
+ mTopLevelAdapter.highlightPreference(mCurrentKey, /* scrollNeeded= */ true);
+ }
+
+ void setHighlightPreferenceKey(String prefKey) {
+ if (mTopLevelAdapter != null) {
+ ensureDialogDismissed();
+ mPreviousKey = mCurrentKey;
+ mCurrentKey = prefKey;
+ mTopLevelAdapter.highlightPreference(prefKey, /* scrollNeeded= */ false);
+ }
+ }
+
+ void highlightPreferenceIfNeeded(FragmentActivity activity) {
+ if (mTopLevelAdapter != null) {
+ mTopLevelAdapter.requestHighlight();
+ }
+ }
+
+ void setMenuHighlightShowed(boolean show) {
+ if (mTopLevelAdapter == null) {
+ return;
+ }
+ ensureDialogDismissed();
+
+ if (show) {
+ mCurrentKey = mHiddenKey;
+ mHiddenKey = null;
+ } else {
+ if (mHiddenKey == null) {
+ mHiddenKey = mCurrentKey;
+ }
+ mCurrentKey = null;
+ }
+ mTopLevelAdapter.highlightPreference(mCurrentKey, /* scrollNeeded= */ show);
+ }
+
+ void setHighlightMenuKey(String menuKey, boolean scrollNeeded) {
+ if (mTopLevelAdapter == null) {
+ return;
+ }
+ ensureDialogDismissed();
+
+ final String prefKey = HighlightableMenu.lookupPreferenceKey(menuKey);
+ if (TextUtils.isEmpty(prefKey)) {
+ Log.e(TAG, "Invalid highlight menu key: " + menuKey);
+ } else {
+ Log.d(TAG, "Menu key: " + menuKey);
+ mCurrentKey = prefKey;
+ mTopLevelAdapter.highlightPreference(prefKey, scrollNeeded);
+ }
+ }
+
+ private static String getHighlightPrefKeyFromArguments(Bundle arguments) {
+ final String menuKey = arguments.getString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY);
+ final String prefKey = HighlightableMenu.lookupPreferenceKey(menuKey);
+ if (TextUtils.isEmpty(prefKey)) {
+ Log.e(TAG, "Invalid highlight menu key: " + menuKey);
+ } else {
+ Log.d(TAG, "Menu key: " + menuKey);
+ }
+ return prefKey;
+ }
+
+ private void ensureDialogDismissed() {
+ if (mDialog != null) {
+ onCancel(mDialog);
+ mDialog.dismiss();
+ }
+ }
+}
diff --git a/src/com/android/settings/homepage/TopLevelSettings.java b/src/com/android/settings/homepage/TopLevelSettings.java
index eb1a066..f2e5a35 100644
--- a/src/com/android/settings/homepage/TopLevelSettings.java
+++ b/src/com/android/settings/homepage/TopLevelSettings.java
@@ -25,7 +25,6 @@
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.text.TextUtils;
-import android.util.Log;
import androidx.fragment.app.Fragment;
import androidx.preference.Preference;
@@ -34,7 +33,6 @@
import androidx.recyclerview.widget.RecyclerView;
import com.android.settings.R;
-import com.android.settings.SettingsActivity;
import com.android.settings.Utils;
import com.android.settings.activityembedding.ActivityEmbeddingRulesController;
import com.android.settings.activityembedding.ActivityEmbeddingUtils;
@@ -42,7 +40,6 @@
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.support.SupportPreferenceController;
-import com.android.settings.widget.HighlightableTopLevelPreferenceAdapter;
import com.android.settings.widget.HomepagePreference;
import com.android.settingslib.core.instrumentation.Instrumentable;
import com.android.settingslib.drawer.Tile;
@@ -53,13 +50,11 @@
PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {
private static final String TAG = "TopLevelSettings";
- private static final String SAVED_HIGHLIGHTED_PREF = "highlighted_pref";
- private static final String SAVED_CACHED_PREF = "cached_pref";
+ private static final String SAVED_HIGHLIGHT_MIXIN = "highlight_mixin";
+ private static final String PREF_KEY_SUPPORT = "top_level_support";
- private HighlightableTopLevelPreferenceAdapter mTopLevelAdapter;
-
- private String mHighlightedPreferenceKey;
- private String mCachedPreferenceKey;
+ private TopLevelHighlightMixin mHighlightMixin;
+ private boolean mFirstStarted = true;
public TopLevelSettings() {
final Bundle args = new Bundle();
@@ -127,17 +122,37 @@
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
- if (icicle != null) {
- mHighlightedPreferenceKey = icicle.getString(SAVED_HIGHLIGHTED_PREF);
- mCachedPreferenceKey = icicle.getString(SAVED_CACHED_PREF);
+ if (!ActivityEmbeddingUtils.isEmbeddingActivityEnabled(getContext())) {
+ return;
}
+
+ if (icicle != null) {
+ mHighlightMixin = icicle.getParcelable(SAVED_HIGHLIGHT_MIXIN);
+ }
+ if (mHighlightMixin == null) {
+ mHighlightMixin = new TopLevelHighlightMixin();
+ }
+ }
+
+ @Override
+ public void onStart() {
+ if (mFirstStarted) {
+ mFirstStarted = false;
+ } else if (!ActivityEmbeddingUtils.isTwoPaneResolution(getActivity())) {
+ // Set default highlight menu key for 1-pane homepage since it will show the placeholder
+ // page once changing back to 2-pane.
+ setHighlightMenuKey(getString(SettingsHomepageActivity.DEFAULT_HIGHLIGHT_MENU_KEY),
+ /* scrollNeeded= */ false);
+ }
+ super.onStart();
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
- outState.putString(SAVED_HIGHLIGHTED_PREF, mHighlightedPreferenceKey);
- outState.putString(SAVED_CACHED_PREF, mCachedPreferenceKey);
+ if (mHighlightMixin != null) {
+ outState.putParcelable(SAVED_HIGHLIGHT_MIXIN, mHighlightMixin);
+ }
}
@Override
@@ -170,58 +185,35 @@
@Override
public void highlightPreferenceIfNeeded() {
- if (mTopLevelAdapter != null) {
- mTopLevelAdapter.requestHighlight();
+ if (mHighlightMixin != null) {
+ mHighlightMixin.highlightPreferenceIfNeeded(getActivity());
}
}
+ /** Returns a {@link TopLevelHighlightMixin} that performs highlighting */
+ public TopLevelHighlightMixin getHighlightMixin() {
+ return mHighlightMixin;
+ }
+
/** Highlight a preference with specified preference key */
public void setHighlightPreferenceKey(String prefKey) {
- if (mTopLevelAdapter != null) {
- mCachedPreferenceKey = null;
- mHighlightedPreferenceKey = prefKey;
- mTopLevelAdapter.highlightPreference(prefKey, /* scrollNeeded= */ false);
+ // Skip Tips & support since it's full screen
+ if (mHighlightMixin != null && !TextUtils.equals(prefKey, PREF_KEY_SUPPORT)) {
+ mHighlightMixin.setHighlightPreferenceKey(prefKey);
}
}
- /** Highlight the previous preference */
- public void restorePreviousHighlight() {
- if (mTopLevelAdapter != null) {
- mTopLevelAdapter.restorePreviousHighlight();
- }
- }
-
- /** Show/hide the highlight on the menu entry */
+ /** Show/hide the highlight on the menu entry for the search page presence */
public void setMenuHighlightShowed(boolean show) {
- if (mTopLevelAdapter == null) {
- return;
+ if (mHighlightMixin != null) {
+ mHighlightMixin.setMenuHighlightShowed(show);
}
-
- if (show) {
- mHighlightedPreferenceKey = mCachedPreferenceKey;
- mCachedPreferenceKey = null;
- } else {
- if (mCachedPreferenceKey == null) {
- mCachedPreferenceKey = mHighlightedPreferenceKey;
- }
- mHighlightedPreferenceKey = null;
- }
- mTopLevelAdapter.highlightPreference(mHighlightedPreferenceKey, /* scrollNeeded= */ show);
}
/** Highlight and scroll to a preference with specified menu key */
- public void setHighlightMenuKey(String menuKey) {
- if (mTopLevelAdapter == null) {
- return;
- }
-
- final String prefKey = HighlightableMenu.lookupPreferenceKey(menuKey);
- if (TextUtils.isEmpty(prefKey)) {
- Log.e(TAG, "Invalid highlight menu key: " + menuKey);
- } else {
- Log.d(TAG, "Menu key: " + menuKey);
- mHighlightedPreferenceKey = prefKey;
- mTopLevelAdapter.highlightPreference(prefKey, /* scrollNeeded= */ true);
+ public void setHighlightMenuKey(String menuKey, boolean scrollNeeded) {
+ if (mHighlightMixin != null) {
+ mHighlightMixin.setHighlightMenuKey(menuKey, scrollNeeded);
}
}
@@ -237,16 +229,7 @@
|| !(getActivity() instanceof SettingsHomepageActivity)) {
return super.onCreateAdapter(preferenceScreen);
}
-
- if (TextUtils.isEmpty(mHighlightedPreferenceKey)) {
- mHighlightedPreferenceKey = getHighlightPrefKeyFromArguments();
- }
-
- Log.d(TAG, "onCreateAdapter, pref key: " + mHighlightedPreferenceKey);
- mTopLevelAdapter = new HighlightableTopLevelPreferenceAdapter(
- (SettingsHomepageActivity) getActivity(), preferenceScreen, getListView(),
- mHighlightedPreferenceKey);
- return mTopLevelAdapter;
+ return mHighlightMixin.onCreateAdapter(this, preferenceScreen);
}
@Override
@@ -255,25 +238,9 @@
}
void reloadHighlightMenuKey() {
- if (mTopLevelAdapter == null) {
- return;
+ if (mHighlightMixin != null) {
+ mHighlightMixin.reloadHighlightMenuKey(getArguments());
}
-
- mHighlightedPreferenceKey = getHighlightPrefKeyFromArguments();
- Log.d(TAG, "reloadHighlightMenuKey, pref key: " + mHighlightedPreferenceKey);
- mTopLevelAdapter.highlightPreference(mHighlightedPreferenceKey, /* scrollNeeded= */ true);
- }
-
- private String getHighlightPrefKeyFromArguments() {
- final Bundle arguments = getArguments();
- final String menuKey = arguments.getString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY);
- final String prefKey = HighlightableMenu.lookupPreferenceKey(menuKey);
- if (TextUtils.isEmpty(prefKey)) {
- Log.e(TAG, "Invalid highlight menu key: " + menuKey);
- } else {
- Log.d(TAG, "Menu key: " + menuKey);
- }
- return prefKey;
}
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
diff --git a/src/com/android/settings/inputmethod/AvailableVirtualKeyboardFragment.java b/src/com/android/settings/inputmethod/AvailableVirtualKeyboardFragment.java
index 7523ae4..b083aef 100644
--- a/src/com/android/settings/inputmethod/AvailableVirtualKeyboardFragment.java
+++ b/src/com/android/settings/inputmethod/AvailableVirtualKeyboardFragment.java
@@ -16,18 +16,21 @@
package com.android.settings.inputmethod;
-import android.app.Activity;
import android.app.admin.DevicePolicyManager;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.res.Configuration;
import android.os.Bundle;
+import android.os.UserHandle;
+import android.os.UserManager;
import android.provider.SearchIndexableResource;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager;
import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.Utils;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.inputmethod.InputMethodAndSubtypeUtilCompat;
import com.android.settingslib.inputmethod.InputMethodPreference;
@@ -38,23 +41,41 @@
import java.util.ArrayList;
import java.util.List;
+/**
+ * The fragment for on-screen keyboard settings which used to display user installed IMEs.
+ *
+ * TODO(b/207452897): Add test for AvailableVirtualKeyboardFragment
+ */
@SearchIndexable
-public final class AvailableVirtualKeyboardFragment extends SettingsPreferenceFragment
+public final class AvailableVirtualKeyboardFragment extends DashboardFragment
implements InputMethodPreference.OnSavePreferenceListener {
+ private static final String TAG = "AvailableVirtualKeyboardFragment";
private final ArrayList<InputMethodPreference> mInputMethodPreferenceList = new ArrayList<>();
private InputMethodSettingValuesWrapper mInputMethodSettingValues;
- private InputMethodManager mImm;
- private DevicePolicyManager mDpm;
+ private Context mUserAwareContext;
+ private int mUserId;
@Override
public void onCreatePreferences(Bundle bundle, String s) {
addPreferencesFromResource(R.xml.available_virtual_keyboard);
- Activity activity = getActivity();
+ mInputMethodSettingValues = InputMethodSettingValuesWrapper.getInstance(mUserAwareContext);
+ }
- mInputMethodSettingValues = InputMethodSettingValuesWrapper.getInstance(activity);
- mImm = activity.getSystemService(InputMethodManager.class);
- mDpm = activity.getSystemService(DevicePolicyManager.class);
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+ final int profileType = getArguments().getInt(ProfileSelectFragment.EXTRA_PROFILE);
+ if (profileType == ProfileSelectFragment.ProfileType.WORK) {
+ final UserManager userManager = UserManager.get(context);
+ final UserHandle workUser = Utils.getManagedProfile(userManager);
+ // get work userId
+ mUserId = Utils.getManagedProfileId(userManager, UserHandle.myUserId());
+ mUserAwareContext = context.createContextAsUser(workUser, 0);
+ } else {
+ mUserId = UserHandle.myUserId();
+ mUserAwareContext = context;
+ }
}
@Override
@@ -67,11 +88,24 @@
}
@Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.available_virtual_keyboard;
+ }
+
+ @Override
+ protected String getLogTag() {
+ return TAG;
+ }
+
+ @Override
public void onSaveInputMethodPreference(final InputMethodPreference pref) {
final boolean hasHardwareKeyboard = getResources().getConfiguration().keyboard
== Configuration.KEYBOARD_QWERTY;
- InputMethodAndSubtypeUtilCompat.saveInputMethodSubtypeList(this, getContentResolver(),
- mImm.getInputMethodList(), hasHardwareKeyboard);
+ InputMethodAndSubtypeUtilCompat.saveInputMethodSubtypeListForUser(this,
+ mUserAwareContext.getContentResolver(),
+ getContext().getSystemService(
+ InputMethodManager.class).getInputMethodListAsUser(mUserId),
+ hasHardwareKeyboard, mUserId);
// Update input method settings and preference list.
mInputMethodSettingValues.refreshAllInputMethodAndSubtypes();
for (final InputMethodPreference p : mInputMethodPreferenceList) {
@@ -88,10 +122,12 @@
mInputMethodSettingValues.refreshAllInputMethodAndSubtypes();
// Clear existing "InputMethodPreference"s
mInputMethodPreferenceList.clear();
- List<String> permittedList = mDpm.getPermittedInputMethodsForCurrentUser();
- final Context context = getPrefContext();
+ final List<String> permittedList = mUserAwareContext.getSystemService(
+ DevicePolicyManager.class).getPermittedInputMethods();
+ final Context prefContext = getPrefContext();
final List<InputMethodInfo> imis = mInputMethodSettingValues.getInputMethodList();
- final List<InputMethodInfo> enabledImis = mImm.getEnabledInputMethodList();
+ final List<InputMethodInfo> enabledImis = getContext().getSystemService(
+ InputMethodManager.class).getEnabledInputMethodListAsUser(mUserId);
final int numImis = (imis == null ? 0 : imis.size());
for (int i = 0; i < numImis; ++i) {
final InputMethodInfo imi = imis.get(i);
@@ -101,12 +137,12 @@
// allowed by organization. Doing so will allow the user to disable the input method and
// remain complaint with the organization's policy. Once disabled, the input method
// cannot be re-enabled because it is not in the permitted list.
- final boolean isAllowedByOrganization = permittedList == null
+ final boolean isAllowedByOrganization = permittedList.isEmpty()
|| permittedList.contains(imi.getPackageName())
|| enabledImis.contains(imi);
- final InputMethodPreference pref = new InputMethodPreference(
- context, imi, isAllowedByOrganization, this);
- pref.setIcon(imi.loadIcon(context.getPackageManager()));
+ final InputMethodPreference pref = new InputMethodPreference(prefContext, imi,
+ isAllowedByOrganization, this, mUserId);
+ pref.setIcon(imi.loadIcon(mUserAwareContext.getPackageManager()));
mInputMethodPreferenceList.add(pref);
}
final Collator collator = Collator.getInstance();
diff --git a/src/com/android/settings/network/SubscriptionUtil.java b/src/com/android/settings/network/SubscriptionUtil.java
index c77a294..d7e5876 100644
--- a/src/com/android/settings/network/SubscriptionUtil.java
+++ b/src/com/android/settings/network/SubscriptionUtil.java
@@ -540,13 +540,14 @@
return null;
}
- TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class);
- String rawPhoneNumber =
- telephonyManager.getLine1Number(subscriptionInfo.getSubscriptionId());
- String countryIso = MccTable.countryCodeForMcc(subscriptionInfo.getMccString());
+ final SubscriptionManager subscriptionManager = context.getSystemService(
+ SubscriptionManager.class);
+ String rawPhoneNumber = subscriptionManager.getPhoneNumber(
+ subscriptionInfo.getSubscriptionId());
if (TextUtils.isEmpty(rawPhoneNumber)) {
return null;
}
+ String countryIso = MccTable.countryCodeForMcc(subscriptionInfo.getMccString());
return PhoneNumberUtils.formatNumber(rawPhoneNumber, countryIso);
}
diff --git a/src/com/android/settings/network/SubscriptionsPreferenceController.java b/src/com/android/settings/network/SubscriptionsPreferenceController.java
index 9e1b6da..5541888 100644
--- a/src/com/android/settings/network/SubscriptionsPreferenceController.java
+++ b/src/com/android/settings/network/SubscriptionsPreferenceController.java
@@ -316,7 +316,7 @@
: (serviceState.getState() == ServiceState.STATE_IN_SERVICE);
if (isDataInService || isVoiceInService || isCarrierNetworkActive) {
icon = mSubsPrefCtrlInjector.getIcon(mContext, level, numLevels,
- !mTelephonyManager.isDataEnabled());
+ !tmForSubId.isDataEnabled());
}
final boolean isActiveCellularNetwork =
diff --git a/src/com/android/settings/network/SwitchSlotSidecar.java b/src/com/android/settings/network/SwitchSlotSidecar.java
index cffb23f..abf8842 100644
--- a/src/com/android/settings/network/SwitchSlotSidecar.java
+++ b/src/com/android/settings/network/SwitchSlotSidecar.java
@@ -19,6 +19,7 @@
import android.annotation.IntDef;
import android.app.FragmentManager;
import android.os.Bundle;
+import android.telephony.SubscriptionInfo;
import android.util.Log;
import com.android.settings.AsyncTaskSidecar;
@@ -41,11 +42,14 @@
})
private @interface Command {
int SWITCH_TO_REMOVABLE_SIM = 0;
+ int SWITCH_TO_EUICC_SIM = 1;
}
static class Param {
@Command int command;
int slotId;
+ int port;
+ SubscriptionInfo removedSubInfo;
}
static class Result {
@@ -65,13 +69,24 @@
}
/** Starts switching to the removable slot. */
- public void runSwitchToRemovableSlot(int id) {
+ public void runSwitchToRemovableSlot(int id, SubscriptionInfo removedSubInfo) {
Param param = new Param();
param.command = Command.SWITCH_TO_REMOVABLE_SIM;
param.slotId = id;
+ param.removedSubInfo = removedSubInfo;
+ param.port = 0;
super.run(param);
}
+ /** Starts switching to the removable slot. */
+ public void runSwitchToEuiccSlot(int id, int port, SubscriptionInfo removedSubInfo) {
+ Param param = new Param();
+ param.command = Command.SWITCH_TO_EUICC_SIM;
+ param.slotId = id;
+ param.removedSubInfo = removedSubInfo;
+ param.port = port;
+ super.run(param);
+ }
/**
* Returns the exception thrown during the execution of a command. Will be null in any state
* other than {@link State#SUCCESS}, and may be null in that state if there was not an error.
@@ -91,7 +106,14 @@
try {
switch (param.command) {
case Command.SWITCH_TO_REMOVABLE_SIM:
- UiccSlotUtil.switchToRemovableSlot(param.slotId, getContext());
+ Log.i(TAG, "Start to switch to removable slot.");
+ UiccSlotUtil.switchToRemovableSlot(getContext(), param.slotId,
+ param.removedSubInfo);
+ break;
+ case Command.SWITCH_TO_EUICC_SIM:
+ Log.i(TAG, "Start to switch to euicc slot.");
+ UiccSlotUtil.switchToEuiccSlot(getContext(), param.slotId, param.port,
+ param.removedSubInfo);
break;
default:
Log.e(TAG, "Wrong command.");
diff --git a/src/com/android/settings/network/SwitchToEuiccSubscriptionSidecar.java b/src/com/android/settings/network/SwitchToEuiccSubscriptionSidecar.java
index 6e6142f..d88a189 100644
--- a/src/com/android/settings/network/SwitchToEuiccSubscriptionSidecar.java
+++ b/src/com/android/settings/network/SwitchToEuiccSubscriptionSidecar.java
@@ -18,17 +18,30 @@
import android.app.FragmentManager;
import android.app.PendingIntent;
+import android.content.Intent;
+import android.telephony.SubscriptionInfo;
+import android.telephony.UiccCardInfo;
+import android.telephony.UiccSlotMapping;
+import android.telephony.euicc.EuiccManager;
+import android.util.Log;
import com.android.settings.SidecarFragment;
import com.android.settings.network.telephony.EuiccOperationSidecar;
+import java.util.Collection;
+import java.util.List;
+import java.util.stream.Collectors;
+
/** A headless fragment encapsulating long-running eSIM enabling/disabling operations. */
public class SwitchToEuiccSubscriptionSidecar extends EuiccOperationSidecar {
private static final String TAG = "SwitchToEuiccSubscriptionSidecar";
private static final String ACTION_SWITCH_TO_SUBSCRIPTION =
"com.android.settings.network.SWITCH_TO_SUBSCRIPTION";
+ private static final int ESIM_SLOT_ID = 1;
private PendingIntent mCallbackIntent;
+ private int mSubId;
+ private int mPort;
/** Returns a SwitchToEuiccSubscriptionSidecar sidecar instance. */
public static SwitchToEuiccSubscriptionSidecar get(FragmentManager fm) {
@@ -46,10 +59,119 @@
return mCallbackIntent;
}
+ @Override
+ public void onStateChange(SidecarFragment fragment) {
+ if (fragment == mSwitchSlotSidecar) {
+ onSwitchSlotSidecarStateChange();
+ } else {
+ Log.wtf(TAG, "Received state change from a sidecar not expected.");
+ }
+ }
+
/** Starts calling EuiccManager#switchToSubscription to enable/disable the eSIM profile. */
+ // ToDo: delete this api and refactor the related code.
public void run(int subscriptionId) {
setState(State.RUNNING, Substate.UNUSED);
mCallbackIntent = createCallbackIntent();
mEuiccManager.switchToSubscription(subscriptionId, mCallbackIntent);
}
+
+ /**
+ * Starts calling EuiccManager#switchToSubscription to enable/disable the eSIM profile.
+ *
+ * @param subscriptionId the esim's subscriptionId.
+ * @param port the esim's portId. If user wants to inactivate esim, then user must to assign the
+ * the port. If user wants to activate esim, then the port can be -1.
+ * @param removedSubInfo if the all of slots have sims, it should remove the one of active sim.
+ * If the removedSubInfo is null, then use the default value.
+ * The default value is the esim slot and portId 0.
+ */
+ public void run(int subscriptionId, int port, SubscriptionInfo removedSubInfo) {
+ setState(State.RUNNING, Substate.UNUSED);
+ mCallbackIntent = createCallbackIntent();
+ mSubId = subscriptionId;
+ // To check whether the esim slot's port is active. If yes, skip setSlotMapping. If no,
+ // set this slot+port into setSimSlotMapping.
+ mPort = (port < 0) ? getTargetPortId(removedSubInfo) : port;
+ Log.i(TAG, "The SubId is " + mSubId + "The port is " + mPort);
+
+ mSwitchSlotSidecar.runSwitchToEuiccSlot(getTargetSlot(), mPort, removedSubInfo);
+ }
+
+ private int getTargetPortId(SubscriptionInfo removedSubInfo) {
+ if (!mTelephonyManager.isMultiSimEnabled() || !isMultipleEnabledProfilesSupported()) {
+ // In the 'SS mode' or 'DSDS+no MEP', the port is 0.
+ return 0;
+ }
+
+ // In the 'DSDS+MEP', if the removedSubInfo is esim, then the port is
+ // removedSubInfo's port.
+ if (removedSubInfo != null && removedSubInfo.isEmbedded()) {
+ return removedSubInfo.getPortIndex();
+ }
+
+ // In DSDS+MEP mode, the removedSubInfo is psim or is null, it means the this esim need
+ // another port in the esim slot.
+ // To find another esim's port and value is from 0;
+ int port = 0;
+ Collection<UiccSlotMapping> uiccSlotMappings = mTelephonyManager.getSimSlotMapping();
+ for (UiccSlotMapping uiccSlotMapping :
+ uiccSlotMappings.stream()
+ .filter(
+ uiccSlotMapping -> uiccSlotMapping.getPhysicalSlotIndex()
+ == getTargetSlot())
+ .collect(Collectors.toList())) {
+ if (uiccSlotMapping.getPortIndex() == port) {
+ port++;
+ }
+ }
+ return port;
+ }
+
+ private int getTargetSlot() {
+ return ESIM_SLOT_ID;
+ }
+
+ private void onSwitchSlotSidecarStateChange() {
+ switch (mSwitchSlotSidecar.getState()) {
+ case State.SUCCESS:
+ mSwitchSlotSidecar.reset();
+ Log.i(TAG,
+ "Successfully SimSlotMapping. Start to enable/disable esim");
+ switchToSubscription();
+ break;
+ case State.ERROR:
+ mSwitchSlotSidecar.reset();
+ Log.i(TAG, "Failed to set SimSlotMapping");
+ setState(State.ERROR, Substate.UNUSED);
+ break;
+ }
+ }
+
+ private boolean isMultipleEnabledProfilesSupported() {
+ List<UiccCardInfo> cardInfos = mTelephonyManager.getUiccCardsInfo();
+ if (cardInfos == null) {
+ Log.w(TAG, "UICC cards info list is empty.");
+ return false;
+ }
+ return cardInfos.stream().anyMatch(
+ cardInfo -> cardInfo.isMultipleEnabledProfilesSupported());
+ }
+
+ private void switchToSubscription() {
+ // The SimSlotMapping is ready, then to execute activate/inactivate esim.
+ EuiccManager.ResultListener callback = new EuiccManager.ResultListener() {
+ @Override
+ public void onComplete(int resultCode, Intent resultIntent) {
+ Log.i(TAG, String.format("Result code : %d;", resultCode));
+ if (resultCode == EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK) {
+ setState(State.SUCCESS, Substate.UNUSED);
+ } else {
+ setState(State.ERROR, resultCode);
+ }
+ }
+ };
+ mEuiccManager.switchToSubscription(mSubId, mPort, getContext().getMainExecutor(),
+ callback);
+ }
}
diff --git a/src/com/android/settings/network/SwitchToRemovableSlotSidecar.java b/src/com/android/settings/network/SwitchToRemovableSlotSidecar.java
index 132a2fd..2c184c6 100644
--- a/src/com/android/settings/network/SwitchToRemovableSlotSidecar.java
+++ b/src/com/android/settings/network/SwitchToRemovableSlotSidecar.java
@@ -38,8 +38,8 @@
// Stateless members.
private SwitchToEuiccSubscriptionSidecar mSwitchToSubscriptionSidecar;
- private SwitchSlotSidecar mSwitchSlotSidecar;
private int mPhysicalSlotId;
+ private SubscriptionInfo mRemovedSubInfo;
/** Returns a SwitchToRemovableSlotSidecar sidecar instance. */
public static SwitchToRemovableSlotSidecar get(FragmentManager fm) {
@@ -51,20 +51,17 @@
super.onCreate(savedInstanceState);
mSwitchToSubscriptionSidecar =
SwitchToEuiccSubscriptionSidecar.get(getChildFragmentManager());
- mSwitchSlotSidecar = SwitchSlotSidecar.get(getChildFragmentManager());
}
@Override
public void onResume() {
super.onResume();
mSwitchToSubscriptionSidecar.addListener(this);
- mSwitchSlotSidecar.addListener(this);
}
@Override
public void onPause() {
mSwitchToSubscriptionSidecar.removeListener(this);
- mSwitchSlotSidecar.removeListener(this);
super.onPause();
}
@@ -90,29 +87,46 @@
*
* @param physicalSlotId removable physical SIM slot ID.
*/
+ // ToDo: delete this api and refactor the related code.
public void run(int physicalSlotId) {
mPhysicalSlotId = physicalSlotId;
SubscriptionManager subscriptionManager =
getContext().getSystemService(SubscriptionManager.class);
if (SubscriptionUtil.getActiveSubscriptions(subscriptionManager).stream()
.anyMatch(SubscriptionInfo::isEmbedded)) {
+ // In SS mode, the esim is active, then inactivate the esim.
Log.i(TAG, "There is an active eSIM profile. Disable the profile first.");
// Use INVALID_SUBSCRIPTION_ID to disable the only active profile.
- mSwitchToSubscriptionSidecar.run(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+ mSwitchToSubscriptionSidecar.run(SubscriptionManager.INVALID_SUBSCRIPTION_ID, 0, null);
} else {
Log.i(TAG, "There is no active eSIM profiles. Start to switch to removable slot.");
- mSwitchSlotSidecar.runSwitchToRemovableSlot(mPhysicalSlotId);
+ mSwitchSlotSidecar.runSwitchToRemovableSlot(mPhysicalSlotId, null);
}
}
+ /**
+ * Starts switching to the removable slot.
+ *
+ * @param physicalSlotId removable physical SIM slot ID.
+ * @param removedSubInfo if the all of slots have sims, it should remove the one of active sim.
+ * If the removedSubInfo is null, then use the default value.
+ * The default value is the removable physical SIM slot and portId 0.
+ */
+ public void run(int physicalSlotId, SubscriptionInfo removedSubInfo) {
+ mPhysicalSlotId = physicalSlotId;
+ mRemovedSubInfo = removedSubInfo;
+
+ Log.i(TAG, "Start to switch to removable slot.");
+ mSwitchSlotSidecar.runSwitchToRemovableSlot(mPhysicalSlotId, mRemovedSubInfo);
+ }
+
private void onSwitchToSubscriptionSidecarStateChange() {
switch (mSwitchToSubscriptionSidecar.getState()) {
case State.SUCCESS:
mSwitchToSubscriptionSidecar.reset();
- Log.i(
- TAG,
+ Log.i(TAG,
"Successfully disabled eSIM profile. Start to switch to Removable slot.");
- mSwitchSlotSidecar.runSwitchToRemovableSlot(mPhysicalSlotId);
+ mSwitchSlotSidecar.runSwitchToRemovableSlot(mPhysicalSlotId, mRemovedSubInfo);
break;
case State.ERROR:
mSwitchToSubscriptionSidecar.reset();
diff --git a/src/com/android/settings/network/UiccSlotUtil.java b/src/com/android/settings/network/UiccSlotUtil.java
index ccf3f91..8938cdb 100644
--- a/src/com/android/settings/network/UiccSlotUtil.java
+++ b/src/com/android/settings/network/UiccSlotUtil.java
@@ -19,8 +19,10 @@
import android.annotation.IntDef;
import android.content.Context;
import android.provider.Settings;
+import android.telephony.SubscriptionInfo;
import android.telephony.TelephonyManager;
import android.telephony.UiccSlotInfo;
+import android.telephony.UiccSlotMapping;
import android.util.Log;
import com.android.settingslib.utils.ThreadUtils;
@@ -29,17 +31,21 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.Collection;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+// ToDo: to do the refactor for renaming
public class UiccSlotUtil {
private static final String TAG = "UiccSlotUtil";
private static final long DEFAULT_WAIT_AFTER_SWITCH_TIMEOUT_MILLIS = 25 * 1000L;
- ;
public static final int INVALID_PHYSICAL_SLOT_ID = -1;
+ public static final int INVALID_PORT_ID = -1;
/**
* Mode for switching to eSIM slot which decides whether there is cleanup process, e.g.
@@ -47,9 +53,9 @@
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef({
- SwitchingEsimMode.NO_CLEANUP,
- SwitchingEsimMode.ASYNC_CLEANUP,
- SwitchingEsimMode.SYNC_CLEANUP
+ SwitchingEsimMode.NO_CLEANUP,
+ SwitchingEsimMode.ASYNC_CLEANUP,
+ SwitchingEsimMode.SYNC_CLEANUP
})
public @interface SwitchingEsimMode {
/** No cleanup process after switching to eSIM slot */
@@ -76,44 +82,108 @@
* Switches to the removable slot. It waits for SIM_STATE_LOADED after switch. If slotId is
* INVALID_PHYSICAL_SLOT_ID, the method will use the first detected inactive removable slot.
*
- * @param slotId the physical removable slot id.
+ * @param slotId the physical removable slot id.
* @param context the application context.
* @throws UiccSlotsException if there is an error.
*/
+ //ToDo: delete this api and refactor the related code.
public static synchronized void switchToRemovableSlot(int slotId, Context context)
throws UiccSlotsException {
+ switchToRemovableSlot(context, slotId, null);
+ }
+
+ /**
+ * Switches to the removable slot. It waits for SIM_STATE_LOADED after switch. If slotId is
+ * INVALID_PHYSICAL_SLOT_ID, the method will use the first detected inactive removable slot.
+ *
+ * @param slotId the physical removable slot id.
+ * @param context the application context.
+ * @param removedSubInfo In the DSDS+MEP mode, if the all of slots have sims, it should
+ * remove the one of active sim.
+ * If the removedSubInfo is null, then use the default value.
+ * The default value is the esim slot and portId 0.
+ * @throws UiccSlotsException if there is an error.
+ */
+ public static synchronized void switchToRemovableSlot(Context context, int slotId,
+ SubscriptionInfo removedSubInfo) throws UiccSlotsException {
if (ThreadUtils.isMainThread()) {
throw new IllegalThreadStateException(
"Do not call switchToRemovableSlot on the main thread.");
}
TelephonyManager telMgr = context.getSystemService(TelephonyManager.class);
- if (telMgr.isMultiSimEnabled()) {
- // If this device supports multiple active slots, don't mess with TelephonyManager.
- Log.i(TAG, "Multiple active slots supported. Not calling switchSlots.");
- return;
- }
- UiccSlotInfo[] slots = telMgr.getUiccSlotsInfo();
- if (slotId == INVALID_PHYSICAL_SLOT_ID) {
- for (int i = 0; i < slots.length; i++) {
- if (slots[i].isRemovable()
- && !slots[i].getPorts().stream().findFirst().get().isActive()
- && slots[i].getCardStateInfo() != UiccSlotInfo.CARD_STATE_INFO_ERROR
- && slots[i].getCardStateInfo() != UiccSlotInfo.CARD_STATE_INFO_RESTRICTED) {
- performSwitchToRemovableSlot(i, context);
- return;
- }
- }
- } else {
- if (slotId >= slots.length || !slots[slotId].isRemovable()) {
- throw new UiccSlotsException("The given slotId is not a removable slot: " + slotId);
- }
- if (!slots[slotId].getPorts().stream().findFirst().get().isActive()) {
- performSwitchToRemovableSlot(slotId, context);
- }
- }
+ int inactiveRemovableSlot = getInactiveRemovableSlot(telMgr.getUiccSlotsInfo(), slotId);
+ performSwitchToSlot(telMgr,
+ prepareUiccSlotMappingsForRemovableSlot(telMgr.getSimSlotMapping(),
+ inactiveRemovableSlot, removedSubInfo, telMgr.isMultiSimEnabled()),
+ context);
}
- private static void performSwitchToRemovableSlot(int slotId, Context context)
+ /**
+ * Switches to the Euicc slot. It waits for SIM_STATE_LOADED after switch.
+ *
+ * @param context the application context.
+ * @param slotId the Euicc slot id.
+ * @param port the Euicc slot port id.
+ * @param removedSubInfo In the DSDS+MEP mode, if the all of slots have sims, it should
+ * remove the one of active sim.
+ * If the removedSubInfo is null, then it uses the default value.
+ * The default value is the esim slot and portId 0.
+ * @throws UiccSlotsException if there is an error.
+ */
+ public static synchronized void switchToEuiccSlot(Context context, int slotId, int port,
+ SubscriptionInfo removedSubInfo) throws UiccSlotsException {
+ if (ThreadUtils.isMainThread()) {
+ throw new IllegalThreadStateException(
+ "Do not call switchToRemovableSlot on the main thread.");
+ }
+ TelephonyManager telMgr = context.getSystemService(TelephonyManager.class);
+ Collection<UiccSlotMapping> uiccSlotMappings = telMgr.getSimSlotMapping();
+ Log.i(TAG, "The SimSlotMapping: " + uiccSlotMappings);
+
+ if (isTargetSlotActive(uiccSlotMappings, slotId, port)) {
+ Log.i(TAG, "The slot is active, then the sim can enable directly.");
+ return;
+ }
+
+ Collection<UiccSlotMapping> newUiccSlotMappings = new ArrayList<>();
+ if (!telMgr.isMultiSimEnabled()) {
+ // In the 'SS mode', the port is 0.
+ newUiccSlotMappings.add(new UiccSlotMapping(port, slotId, 0));
+ } else {
+ // DSDS+MEP
+ // The target slot+port is not active, but the all of logical slots are full. It
+ // needs to replace one of logical slots.
+ int removedSlot =
+ (removedSubInfo != null) ? removedSubInfo.getSimSlotIndex() : slotId;
+ int removedPort = (removedSubInfo != null) ? removedSubInfo.getPortIndex() : 0;
+ Log.i(TAG,
+ String.format("Start to set SimSlotMapping from slot%d-port%d to slot%d-port%d",
+ slotId, port, removedSlot, removedPort));
+ newUiccSlotMappings =
+ uiccSlotMappings.stream().map(uiccSlotMapping -> {
+ if (uiccSlotMapping.getPhysicalSlotIndex() == removedSlot
+ && uiccSlotMapping.getPortIndex() == removedPort) {
+ return new UiccSlotMapping(port, slotId,
+ uiccSlotMapping.getLogicalSlotIndex());
+ }
+ return uiccSlotMapping;
+ }).collect(Collectors.toList());
+ }
+
+ Log.i(TAG, "The SimSlotMapping: " + newUiccSlotMappings);
+ performSwitchToSlot(telMgr, newUiccSlotMappings, context);
+ }
+
+ private static boolean isTargetSlotActive(Collection<UiccSlotMapping> uiccSlotMappings,
+ int slotId, int port) {
+ return uiccSlotMappings.stream()
+ .anyMatch(
+ uiccSlotMapping -> uiccSlotMapping.getPhysicalSlotIndex() == slotId
+ && uiccSlotMapping.getPortIndex() == port);
+ }
+
+ private static void performSwitchToSlot(TelephonyManager telMgr,
+ Collection<UiccSlotMapping> uiccSlotMappings, Context context)
throws UiccSlotsException {
CarrierConfigChangedReceiver receiver = null;
long waitingTimeMillis =
@@ -125,7 +195,7 @@
CountDownLatch latch = new CountDownLatch(1);
receiver = new CarrierConfigChangedReceiver(latch);
receiver.registerOn(context);
- switchSlots(context, slotId);
+ telMgr.setSimSlotMapping(uiccSlotMappings);
latch.await(waitingTimeMillis, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
@@ -138,22 +208,80 @@
}
/**
- * Changes the logical slot to physical slot mapping. OEM should override this to provide
- * device-specific implementation if the device supports switching slots.
- *
- * @param context the application context.
- * @param physicalSlots List of physical slot ids in the order of logical slots.
+ * @param slots The UiccSlotInfo list.
+ * @param slotId The physical removable slot id.
+ * @return The inactive physical removable slot id. If the physical removable slot id is
+ * active, then return -1.
+ * @throws UiccSlotsException if there is an error.
*/
- private static void switchSlots(Context context, int... physicalSlots)
+ private static int getInactiveRemovableSlot(UiccSlotInfo[] slots, int slotId)
throws UiccSlotsException {
- TelephonyManager telMgr = context.getSystemService(TelephonyManager.class);
- if (telMgr.isMultiSimEnabled()) {
- // If this device supports multiple active slots, don't mess with TelephonyManager.
- Log.i(TAG, "Multiple active slots supported. Not calling switchSlots.");
- return;
+ if (slots == null) {
+ throw new UiccSlotsException("UiccSlotInfo is null");
}
- if (!telMgr.switchSlots(physicalSlots)) {
- throw new UiccSlotsException("Failed to switch slots");
+ if (slotId == INVALID_PHYSICAL_SLOT_ID) {
+ for (int i = 0; i < slots.length; i++) {
+ if (slots[i].isRemovable()
+ && !slots[i].getPorts().stream().findFirst().get().isActive()
+ && slots[i].getCardStateInfo() != UiccSlotInfo.CARD_STATE_INFO_ERROR
+ && slots[i].getCardStateInfo() != UiccSlotInfo.CARD_STATE_INFO_RESTRICTED) {
+ return i;
+ }
+ }
+ } else {
+ if (slotId >= slots.length || !slots[slotId].isRemovable()) {
+ throw new UiccSlotsException("The given slotId is not a removable slot: " + slotId);
+ }
+ if (!slots[slotId].getPorts().stream().findFirst().get().isActive()) {
+ return slotId;
+ }
}
+ return INVALID_PHYSICAL_SLOT_ID;
+ }
+
+ private static Collection<UiccSlotMapping> prepareUiccSlotMappingsForRemovableSlot(
+ Collection<UiccSlotMapping> uiccSlotMappings, int slotId,
+ SubscriptionInfo removedSubInfo, boolean isMultiSimEnabled) {
+ if (slotId == INVALID_PHYSICAL_SLOT_ID
+ || uiccSlotMappings.stream().anyMatch(uiccSlotMapping ->
+ uiccSlotMapping.getPhysicalSlotIndex() == slotId
+ && uiccSlotMapping.getPortIndex() == 0)) {
+ // The slot is invalid slot id, then to skip this.
+ // The slot is active, then the sim can enable directly.
+ return uiccSlotMappings;
+ }
+
+ Collection<UiccSlotMapping> newUiccSlotMappings = new ArrayList<>();
+ if (!isMultiSimEnabled) {
+ // In the 'SS mode', the port is 0.
+ newUiccSlotMappings.add(new UiccSlotMapping(0, slotId, 0));
+ } else if (removedSubInfo != null) {
+ // DSDS+MEP
+ // The target slot+port is not active, but the all of logical slots are full. It
+ // needs to replace one of logical slots.
+ Log.i(TAG,
+ String.format("Start to set SimSlotMapping from slot%d-port%d to slot%d-port%d",
+ slotId, 0, removedSubInfo.getSimSlotIndex(),
+ removedSubInfo.getPortIndex()));
+ newUiccSlotMappings =
+ uiccSlotMappings.stream().map(uiccSlotMapping -> {
+ if (uiccSlotMapping.getPhysicalSlotIndex()
+ == removedSubInfo.getSimSlotIndex()
+ && uiccSlotMapping.getPortIndex()
+ == removedSubInfo.getPortIndex()) {
+ return new UiccSlotMapping(0, slotId,
+ uiccSlotMapping.getLogicalSlotIndex());
+ }
+ return uiccSlotMapping;
+ }).collect(Collectors.toList());
+ } else {
+ // DSDS+no MEP
+ // The removable slot should be in UiccSlotMapping.
+ newUiccSlotMappings = uiccSlotMappings;
+ Log.i(TAG, "The removedSubInfo is null");
+ }
+
+ Log.i(TAG, "The SimSlotMapping: " + newUiccSlotMappings);
+ return newUiccSlotMappings;
}
}
diff --git a/src/com/android/settings/network/telephony/AlertDialogFragment.java b/src/com/android/settings/network/telephony/AlertDialogFragment.java
index 5940789..aaccc2d 100644
--- a/src/com/android/settings/network/telephony/AlertDialogFragment.java
+++ b/src/com/android/settings/network/telephony/AlertDialogFragment.java
@@ -16,13 +16,14 @@
package com.android.settings.network.telephony;
-import android.app.Activity;
-import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.text.TextUtils;
+import androidx.appcompat.app.AlertDialog;
+import androidx.fragment.app.FragmentActivity;
+
/** Fragment to show an alert dialog which only has the positive button. */
public class AlertDialogFragment extends BaseDialogFragment
implements DialogInterface.OnClickListener {
@@ -37,13 +38,13 @@
* @param title
* @param msg
*/
- public static void show(Activity activity, String title, String msg) {
+ public static void show(FragmentActivity activity, String title, String msg) {
AlertDialogFragment fragment = new AlertDialogFragment();
Bundle arguments = new Bundle();
arguments.putString(ARG_TITLE, title);
arguments.putString(ARG_MSG, msg);
fragment.setArguments(arguments);
- fragment.show(activity.getFragmentManager(), TAG);
+ fragment.show(activity.getSupportFragmentManager(), TAG);
}
@Override
@@ -55,7 +56,7 @@
if (!TextUtils.isEmpty(getArguments().getString(ARG_MSG))) {
builder.setMessage(getArguments().getString(ARG_MSG));
}
- return builder.show();
+ return builder.create();
}
@Override
diff --git a/src/com/android/settings/network/telephony/BaseDialogFragment.java b/src/com/android/settings/network/telephony/BaseDialogFragment.java
index 7da3259..0465cef 100644
--- a/src/com/android/settings/network/telephony/BaseDialogFragment.java
+++ b/src/com/android/settings/network/telephony/BaseDialogFragment.java
@@ -17,11 +17,11 @@
package com.android.settings.network.telephony;
import android.app.Activity;
-import android.app.DialogFragment;
-import android.app.Fragment;
import android.os.Bundle;
import androidx.annotation.Nullable;
+import androidx.fragment.app.DialogFragment;
+import androidx.fragment.app.Fragment;
/**
* Base dialog fragment class with the functionality to make a fragment or an activity as a listener
diff --git a/src/com/android/settings/network/telephony/ConfirmDialogFragment.java b/src/com/android/settings/network/telephony/ConfirmDialogFragment.java
index 1ba99c5..bad981a 100644
--- a/src/com/android/settings/network/telephony/ConfirmDialogFragment.java
+++ b/src/com/android/settings/network/telephony/ConfirmDialogFragment.java
@@ -16,13 +16,24 @@
package com.android.settings.network.telephony;
-import android.app.Activity;
-import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import androidx.appcompat.app.AlertDialog;
+import androidx.fragment.app.FragmentActivity;
+
+import com.android.settings.R;
+
+import java.util.ArrayList;
/** Fragment to show a confirm dialog. The caller should implement onConfirmListener. */
public class ConfirmDialogFragment extends BaseDialogFragment
@@ -32,22 +43,27 @@
private static final String ARG_MSG = "msg";
private static final String ARG_POS_BUTTON_STRING = "pos_button_string";
private static final String ARG_NEG_BUTTON_STRING = "neg_button_string";
+ private static final String ARG_LIST = "list";
/**
* Interface defining the method that will be invoked when the user has done with the dialog.
*/
public interface OnConfirmListener {
/**
- * @param tag The tag in the caller.
- * @param confirmed True if the user has clicked the positive button. False if the user has
- * clicked the negative button or cancel the dialog.
+ * @param tag The tag in the caller.
+ * @param confirmed True if the user has clicked the positive button. False if the
+ * user has
+ * clicked the negative button or cancel the dialog.
+ * @param itemPosition It is the position of item, if user selects one of the list item.
+ * If the user select "cancel" or the dialog does not have list, then
+ * the value is -1.
*/
- void onConfirm(int tag, boolean confirmed);
+ void onConfirm(int tag, boolean confirmed, int itemPosition);
}
/** Displays a confirmation dialog which has confirm and cancel buttons. */
public static <T> void show(
- Activity activity,
+ FragmentActivity activity,
Class<T> callbackInterfaceClass,
int tagInCaller,
String title,
@@ -62,7 +78,29 @@
arguments.putString(ARG_NEG_BUTTON_STRING, negButtonString);
setListener(activity, null, callbackInterfaceClass, tagInCaller, arguments);
fragment.setArguments(arguments);
- fragment.show(activity.getFragmentManager(), TAG);
+ fragment.show(activity.getSupportFragmentManager(), TAG);
+ }
+
+ /** Displays a confirmation dialog which has confirm and cancel buttons and carrier list.*/
+ public static <T> void show(
+ FragmentActivity activity,
+ Class<T> callbackInterfaceClass,
+ int tagInCaller,
+ String title,
+ String msg,
+ String posButtonString,
+ String negButtonString,
+ ArrayList<String> list) {
+ ConfirmDialogFragment fragment = new ConfirmDialogFragment();
+ Bundle arguments = new Bundle();
+ arguments.putString(ARG_TITLE, title);
+ arguments.putCharSequence(ARG_MSG, msg);
+ arguments.putString(ARG_POS_BUTTON_STRING, posButtonString);
+ arguments.putString(ARG_NEG_BUTTON_STRING, negButtonString);
+ arguments.putStringArrayList(ARG_LIST, list);
+ setListener(activity, null, callbackInterfaceClass, tagInCaller, arguments);
+ fragment.setArguments(arguments);
+ fragment.show(activity.getSupportFragmentManager(), TAG);
}
@Override
@@ -71,37 +109,77 @@
String message = getArguments().getString(ARG_MSG);
String posBtnString = getArguments().getString(ARG_POS_BUTTON_STRING);
String negBtnString = getArguments().getString(ARG_NEG_BUTTON_STRING);
+ ArrayList<String> list = getArguments().getStringArrayList(ARG_LIST);
- Log.i("Showing dialog with title = %s", title);
+ Log.i(TAG, "Showing dialog with title =" + title);
AlertDialog.Builder builder =
new AlertDialog.Builder(getContext())
.setTitle(title)
.setPositiveButton(posBtnString, this)
.setNegativeButton(negBtnString, this);
- if (!TextUtils.isEmpty(message)) {
- builder.setMessage(message);
+ if (list != null && !list.isEmpty()) {
+ Log.i(TAG, "list =" + list.toString());
+
+ View content = LayoutInflater.from(getContext()).inflate(
+ R.layout.sim_confirm_dialog_multiple_enabled_profiles_supported, null);
+
+ TextView dialogMessage = content.findViewById(R.id.msg);
+ if (!TextUtils.isEmpty(message) && dialogMessage != null) {
+ dialogMessage.setText(message);
+ }
+
+ final ArrayAdapter<String> arrayAdapterItems = new ArrayAdapter<String>(
+ getContext(), android.R.layout.select_dialog_item, list);
+ final ListView lvItems = content.findViewById(R.id.carrier_list);
+ if (lvItems != null) {
+ lvItems.setAdapter(arrayAdapterItems);
+ lvItems.setChoiceMode(ListView.CHOICE_MODE_NONE);
+ lvItems.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView<?> parent, View view, int position,
+ long id) {
+ Log.i(TAG, "list onClick =" + position);
+ Log.i(TAG, "list item =" + list.get(position));
+
+ if (position == list.size() - 1) {
+ // user select the "cancel" item;
+ informCaller(false, -1);
+ } else {
+ informCaller(true, position);
+ }
+ }
+ });
+ }
+ builder.setView(content);
+ } else {
+ if (!TextUtils.isEmpty(message)) {
+ builder.setMessage(message);
+ }
}
- AlertDialog dialog = builder.show();
+
+ AlertDialog dialog = builder.create();
dialog.setCanceledOnTouchOutside(false);
return dialog;
}
@Override
public void onClick(DialogInterface dialog, int which) {
- informCaller(which == DialogInterface.BUTTON_POSITIVE);
+ Log.i(TAG, "dialog onClick =" + which);
+
+ informCaller(which == DialogInterface.BUTTON_POSITIVE, -1);
}
@Override
public void onCancel(DialogInterface dialog) {
- informCaller(false);
+ informCaller(false, -1);
}
- private void informCaller(boolean confirmed) {
+ private void informCaller(boolean confirmed, int itemPosition) {
OnConfirmListener listener = getListener(OnConfirmListener.class);
if (listener == null) {
return;
}
- listener.onConfirm(getTagInCaller(), confirmed);
+ listener.onConfirm(getTagInCaller(), confirmed, itemPosition);
}
}
diff --git a/src/com/android/settings/network/telephony/DeleteEuiccSubscriptionDialogActivity.java b/src/com/android/settings/network/telephony/DeleteEuiccSubscriptionDialogActivity.java
index f429f8b..8247f63 100644
--- a/src/com/android/settings/network/telephony/DeleteEuiccSubscriptionDialogActivity.java
+++ b/src/com/android/settings/network/telephony/DeleteEuiccSubscriptionDialogActivity.java
@@ -96,7 +96,7 @@
}
@Override
- public void onConfirm(int tag, boolean confirmed) {
+ public void onConfirm(int tag, boolean confirmed, int itemPosition) {
if (!confirmed) {
finish();
return;
diff --git a/src/com/android/settings/network/telephony/EuiccOperationSidecar.java b/src/com/android/settings/network/telephony/EuiccOperationSidecar.java
index 05c866e..d1d362b 100644
--- a/src/com/android/settings/network/telephony/EuiccOperationSidecar.java
+++ b/src/com/android/settings/network/telephony/EuiccOperationSidecar.java
@@ -24,10 +24,12 @@
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.SystemClock;
+import android.telephony.TelephonyManager;
import android.telephony.euicc.EuiccManager;
import android.util.Log;
import com.android.settings.SidecarFragment;
+import com.android.settings.network.SwitchSlotSidecar;
import java.util.concurrent.atomic.AtomicInteger;
@@ -37,7 +39,8 @@
* should implement its own get() function to return an instance of that class, and implement the
* functional class like run() to actually trigger the function in EuiccManager.
*/
-public abstract class EuiccOperationSidecar extends SidecarFragment {
+public abstract class EuiccOperationSidecar extends SidecarFragment
+ implements SidecarFragment.Listener{
private static final String TAG = "EuiccOperationSidecar";
private static final int REQUEST_CODE = 0;
private static final String EXTRA_OP_ID = "op_id";
@@ -45,6 +48,9 @@
new AtomicInteger((int) SystemClock.elapsedRealtime());
protected EuiccManager mEuiccManager;
+ protected TelephonyManager mTelephonyManager;
+ protected SwitchSlotSidecar mSwitchSlotSidecar;
+
private int mResultCode;
private int mDetailedCode;
@@ -107,6 +113,8 @@
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mEuiccManager = getContext().getSystemService(EuiccManager.class);
+ mTelephonyManager = getContext().getSystemService(TelephonyManager.class);
+ mSwitchSlotSidecar = SwitchSlotSidecar.get(getChildFragmentManager());
getContext()
.getApplicationContext()
@@ -119,11 +127,41 @@
}
@Override
+ public void onResume() {
+ super.onResume();
+ mSwitchSlotSidecar.addListener(this);
+ }
+
+ @Override
+ public void onPause() {
+ mSwitchSlotSidecar.removeListener(this);
+ super.onPause();
+ }
+
+ @Override
public void onDestroy() {
getContext().getApplicationContext().unregisterReceiver(mReceiver);
super.onDestroy();
}
+ @Override
+ public void onStateChange(SidecarFragment fragment) {
+ if (fragment == mSwitchSlotSidecar) {
+ switch (mSwitchSlotSidecar.getState()) {
+ case State.SUCCESS:
+ mSwitchSlotSidecar.reset();
+ Log.i(TAG, "mSwitchSlotSidecar SUCCESS");
+ break;
+ case State.ERROR:
+ mSwitchSlotSidecar.reset();
+ Log.i(TAG, "mSwitchSlotSidecar ERROR");
+ break;
+ }
+ } else {
+ Log.wtf(TAG, "Received state change from a sidecar not expected.");
+ }
+ }
+
public int getResultCode() {
return mResultCode;
}
diff --git a/src/com/android/settings/network/telephony/NetworkSelectSettings.java b/src/com/android/settings/network/telephony/NetworkSelectSettings.java
index d20cc27..b26e783 100644
--- a/src/com/android/settings/network/telephony/NetworkSelectSettings.java
+++ b/src/com/android/settings/network/telephony/NetworkSelectSettings.java
@@ -19,6 +19,7 @@
import android.app.Activity;
import android.app.settings.SettingsEnums;
import android.content.Context;
+import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
@@ -102,7 +103,7 @@
@VisibleForTesting
protected void onCreateInitialization() {
mUseNewApi = enableNewAutoSelectNetworkUI(getContext());
- mSubId = getArguments().getInt(Settings.EXTRA_SUB_ID);
+ mSubId = getSubId();
mPreferenceCategory = getPreferenceCategory(PREF_KEY_NETWORK_OPERATORS);
mStatusMessagePreference = new Preference(getContext());
@@ -121,7 +122,7 @@
mMetricsFeatureProvider = getMetricsFeatureProvider(getContext());
mIsAggregationEnabled = enableAggregation(getContext());
Log.d(TAG, "init: mUseNewApi:" + mUseNewApi
- + " ,mIsAggregationEnabled:" + mIsAggregationEnabled);
+ + " ,mIsAggregationEnabled:" + mIsAggregationEnabled + " ,mSubId:" + mSubId);
}
@Keep
@@ -175,6 +176,18 @@
getPreferenceScreen().setEnabled(enable);
}
+ @Keep
+ @VisibleForTesting
+ protected int getSubId() {
+ int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+ Intent intent = getActivity().getIntent();
+ if (intent != null) {
+ subId = intent.getIntExtra(Settings.EXTRA_SUB_ID,
+ SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+ }
+ return subId;
+ }
+
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
diff --git a/src/com/android/settings/network/telephony/SubscriptionActionDialogActivity.java b/src/com/android/settings/network/telephony/SubscriptionActionDialogActivity.java
index 7ff0d9a..288f1ac 100644
--- a/src/com/android/settings/network/telephony/SubscriptionActionDialogActivity.java
+++ b/src/com/android/settings/network/telephony/SubscriptionActionDialogActivity.java
@@ -16,12 +16,13 @@
package com.android.settings.network.telephony;
-import android.app.Activity;
import android.os.Bundle;
import android.telephony.SubscriptionManager;
+import androidx.fragment.app.FragmentActivity;
+
/** The base class for subscription action dialogs */
-public class SubscriptionActionDialogActivity extends Activity {
+public class SubscriptionActionDialogActivity extends FragmentActivity {
private static final String TAG = "SubscriptionActionDialogActivity";
// Arguments
diff --git a/src/com/android/settings/network/telephony/ToggleSubscriptionDialogActivity.java b/src/com/android/settings/network/telephony/ToggleSubscriptionDialogActivity.java
index 2f6e8a1..cc2986d 100644
--- a/src/com/android/settings/network/telephony/ToggleSubscriptionDialogActivity.java
+++ b/src/com/android/settings/network/telephony/ToggleSubscriptionDialogActivity.java
@@ -23,6 +23,7 @@
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
+import android.telephony.UiccCardInfo;
import android.telephony.UiccSlotInfo;
import android.text.TextUtils;
import android.util.Log;
@@ -40,7 +41,9 @@
import com.google.common.collect.ImmutableList;
+import java.util.ArrayList;
import java.util.List;
+import java.util.stream.Collectors;
/** This dialog activity handles both eSIM and pSIM subscriptions enabling and disabling. */
public class ToggleSubscriptionDialogActivity extends SubscriptionActionDialogActivity
@@ -55,6 +58,8 @@
private static final int DIALOG_TAG_ENABLE_SIM_CONFIRMATION = 2;
private static final int DIALOG_TAG_ENABLE_DSDS_CONFIRMATION = 3;
private static final int DIALOG_TAG_ENABLE_DSDS_REBOOT_CONFIRMATION = 4;
+ private static final int DIALOG_TAG_ENABLE_SIM_CONFIRMATION_MEP = 5;
+
// Number of SIMs for DSDS
private static final int NUM_OF_SIMS_FOR_DSDS = 2;
// Support RTL mode
@@ -85,11 +90,11 @@
private boolean mIsEsimOperation;
private TelephonyManager mTelMgr;
private boolean isRtlMode;
+ private List<SubscriptionInfo> mActiveSubInfos;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
-
Intent intent = getIntent();
int subId = intent.getIntExtra(ARG_SUB_ID, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
mTelMgr = getSystemService(TelephonyManager.class);
@@ -107,6 +112,7 @@
return;
}
+ mActiveSubInfos = SubscriptionUtil.getActiveSubscriptions(mSubscriptionManager);
mSubInfo = SubscriptionUtil.getSubById(mSubscriptionManager, subId);
mIsEsimOperation = mSubInfo != null && mSubInfo.isEmbedded();
mSwitchToEuiccSubscriptionSidecar =
@@ -116,6 +122,7 @@
mEnable = intent.getBooleanExtra(ARG_enable, true);
isRtlMode = getResources().getConfiguration().getLayoutDirection()
== View.LAYOUT_DIRECTION_RTL;
+ Log.i(TAG, "isMultipleEnabledProfilesSupported():" + isMultipleEnabledProfilesSupported());
if (savedInstanceState == null) {
if (mEnable) {
@@ -154,7 +161,7 @@
}
@Override
- public void onConfirm(int tag, boolean confirmed) {
+ public void onConfirm(int tag, boolean confirmed, int itemPosition) {
if (!confirmed
&& tag != DIALOG_TAG_ENABLE_DSDS_CONFIRMATION
&& tag != DIALOG_TAG_ENABLE_DSDS_REBOOT_CONFIRMATION) {
@@ -162,14 +169,16 @@
return;
}
+ SubscriptionInfo removedSubInfo = null;
switch (tag) {
case DIALOG_TAG_DISABLE_SIM_CONFIRMATION:
if (mIsEsimOperation) {
Log.i(TAG, "Disabling the eSIM profile.");
showProgressDialog(
getString(R.string.privileged_action_disable_sub_dialog_progress));
+ int port = mSubInfo != null ? mSubInfo.getPortIndex() : 0;
mSwitchToEuiccSubscriptionSidecar.run(
- SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+ SubscriptionManager.INVALID_SUBSCRIPTION_ID, port, null);
return;
}
Log.i(TAG, "Disabling the pSIM profile.");
@@ -201,6 +210,11 @@
SimActivationNotifier.setShowSimSettingsNotification(this, true);
mTelMgr.switchMultiSimConfig(NUM_OF_SIMS_FOR_DSDS);
break;
+ case DIALOG_TAG_ENABLE_SIM_CONFIRMATION_MEP:
+ if (itemPosition != -1) {
+ removedSubInfo = (mActiveSubInfos != null) ? mActiveSubInfos.get(itemPosition)
+ : null;
+ }
case DIALOG_TAG_ENABLE_SIM_CONFIRMATION:
Log.i(TAG, "User confirmed to enable the subscription.");
if (mIsEsimOperation) {
@@ -209,12 +223,15 @@
R.string.sim_action_switch_sub_dialog_progress,
SubscriptionUtil.getUniqueSubscriptionDisplayName(
mSubInfo, this)));
- mSwitchToEuiccSubscriptionSidecar.run(mSubInfo.getSubscriptionId());
+ mSwitchToEuiccSubscriptionSidecar.run(mSubInfo.getSubscriptionId(),
+ UiccSlotUtil.INVALID_PORT_ID,
+ removedSubInfo);
return;
}
showProgressDialog(
getString(R.string.sim_action_enabling_sim_without_carrier_name));
- mSwitchToRemovableSlotSidecar.run(UiccSlotUtil.INVALID_PHYSICAL_SLOT_ID);
+ mSwitchToRemovableSlotSidecar.run(UiccSlotUtil.INVALID_PHYSICAL_SLOT_ID,
+ removedSubInfo);
break;
default:
Log.e(TAG, "Unrecognized confirmation dialog tag: " + tag);
@@ -225,8 +242,7 @@
private void handleSwitchToEuiccSubscriptionSidecarStateChange() {
switch (mSwitchToEuiccSubscriptionSidecar.getState()) {
case SidecarFragment.State.SUCCESS:
- Log.i(
- TAG,
+ Log.i(TAG,
String.format(
"Successfully %s the eSIM profile.",
mEnable ? "enable" : "disable"));
@@ -235,8 +251,7 @@
finish();
break;
case SidecarFragment.State.ERROR:
- Log.i(
- TAG,
+ Log.i(TAG,
String.format(
"Failed to %s the eSIM profile.", mEnable ? "enable" : "disable"));
mSwitchToEuiccSubscriptionSidecar.reset();
@@ -290,7 +305,8 @@
if (mIsEsimOperation) {
Log.i(TAG, "DSDS enabled, start to enable profile: " + mSubInfo.getSubscriptionId());
// For eSIM operations, we simply switch to the selected eSIM profile.
- mSwitchToEuiccSubscriptionSidecar.run(mSubInfo.getSubscriptionId());
+ mSwitchToEuiccSubscriptionSidecar.run(mSubInfo.getSubscriptionId(),
+ UiccSlotUtil.INVALID_PORT_ID, null);
return;
}
@@ -305,10 +321,8 @@
mSubscriptionManager.setUiccApplicationsEnabled(mSubInfo.getSubscriptionId(), mEnable);
finish();
} else {
- Log.i(
- TAG,
- "The device does not support toggling pSIM. It is enough to just "
- + "enable the removable slot.");
+ Log.i(TAG, "The device does not support toggling pSIM. It is enough to just "
+ + "enable the removable slot.");
}
}
@@ -319,7 +333,10 @@
showEnableDsdsConfirmDialog();
return;
}
- if (!mIsEsimOperation && mTelMgr.isMultiSimEnabled()) {
+ if (!mIsEsimOperation && mTelMgr.isMultiSimEnabled()
+ && isRemovableSimEnabled()) {
+ // This case is for switching on psim when device is not multiple enable profile
+ // supported.
Log.i(TAG, "Toggle on pSIM, no dialog displayed.");
handleTogglePsimAction();
finish();
@@ -372,27 +389,55 @@
}
private void showEnableSimConfirmDialog() {
- List<SubscriptionInfo> activeSubs =
- SubscriptionUtil.getActiveSubscriptions(mSubscriptionManager);
- SubscriptionInfo activeSub = activeSubs.isEmpty() ? null : activeSubs.get(0);
- if (activeSub == null) {
+ if (mActiveSubInfos == null || mActiveSubInfos.isEmpty()) {
Log.i(TAG, "No active subscriptions available.");
showNonSwitchSimConfirmDialog();
return;
}
- Log.i(TAG, "Found active subscription.");
- boolean isBetweenEsim = mIsEsimOperation && activeSub.isEmbedded();
- if (mTelMgr.isMultiSimEnabled() && !isBetweenEsim) {
+ Log.i(TAG, "mActiveSubInfos:" + mActiveSubInfos);
+
+ boolean isSwitchingBetweenEsims = mIsEsimOperation
+ && mActiveSubInfos.stream().anyMatch(activeSubInfo -> activeSubInfo.isEmbedded());
+ boolean isMultiSimEnabled = mTelMgr.isMultiSimEnabled();
+ if (isMultiSimEnabled
+ && !isMultipleEnabledProfilesSupported()
+ && !isSwitchingBetweenEsims) {
+ // Showing the "no switch dialog" for below cases.
+ // DSDS mode + no MEP +
+ // (there is the active psim -> esim switch on => active (psim + esim))
showNonSwitchSimConfirmDialog();
return;
}
+ if (isMultiSimEnabled && isMultipleEnabledProfilesSupported()) {
+ if (mActiveSubInfos.size() < NUM_OF_SIMS_FOR_DSDS) {
+ // The sim can add into device directly, so showing the "no switch dialog".
+ // DSDS + MEP + (active sim < NUM_OF_SIMS_FOR_DSDS)
+ showNonSwitchSimConfirmDialog();
+ } else {
+ // The all of slots have sim, it needs to show the "MEP switch dialog".
+ // DSDS + MEP + two active sims
+ showMepSwitchSimConfirmDialog();
+ }
+ return;
+ }
+
+ // Showing the "switch dialog" for below cases.
+ // case1: SS mode + psim switch on from esim.
+ // case2: SS mode + esim switch from psim.
+ // case3: DSDS mode + No MEP + esim switch on from another esim.
+ SubscriptionInfo activeSub =
+ (isMultiSimEnabled && isSwitchingBetweenEsims)
+ ? mActiveSubInfos.stream()
+ .filter(activeSubInfo -> activeSubInfo.isEmbedded())
+ .findFirst().get()
+ : mActiveSubInfos.get(0);
ConfirmDialogFragment.show(
this,
ConfirmDialogFragment.OnConfirmListener.class,
DIALOG_TAG_ENABLE_SIM_CONFIRMATION,
getSwitchSubscriptionTitle(),
- getSwitchDialogBodyMsg(activeSub, isBetweenEsim),
+ getSwitchDialogBodyMsg(activeSub, isSwitchingBetweenEsims),
getSwitchDialogPosBtnText(),
getString(R.string.sim_action_cancel));
}
@@ -408,6 +453,35 @@
getString(R.string.sim_action_cancel));
}
+ private void showMepSwitchSimConfirmDialog() {
+ Log.i(TAG, "showMepSwitchSimConfirmDialog");
+ final CharSequence displayName = SubscriptionUtil.getUniqueSubscriptionDisplayName(
+ mSubInfo, this);
+ String title = getString(R.string.sim_action_switch_sub_dialog_mep_title, displayName);
+ final StringBuilder switchDialogMsg = new StringBuilder();
+ switchDialogMsg.append(
+ getString(R.string.sim_action_switch_sub_dialog_mep_text, displayName));
+ if (isRtlMode) {
+ /* There are two lines of message in the dialog, and the RTL symbols must be added
+ * before and after each sentence, so use the line break symbol to find the position.
+ * (Each message are all with two line break symbols)
+ */
+ switchDialogMsg.insert(0, RTL_MARK)
+ .insert(switchDialogMsg.indexOf(LINE_BREAK) - LINE_BREAK_OFFSET_ONE, RTL_MARK)
+ .insert(switchDialogMsg.indexOf(LINE_BREAK) + LINE_BREAK_OFFSET_TWO, RTL_MARK)
+ .insert(switchDialogMsg.length(), RTL_MARK);
+ }
+ ConfirmDialogFragment.show(
+ this,
+ ConfirmDialogFragment.OnConfirmListener.class,
+ DIALOG_TAG_ENABLE_SIM_CONFIRMATION_MEP,
+ title,
+ switchDialogMsg.toString(),
+ null,
+ null,
+ getSwitchDialogBodyList());
+ }
+
private String getSwitchDialogPosBtnText() {
return mIsEsimOperation
? getString(
@@ -468,6 +542,20 @@
return switchDialogMsg.toString();
}
+ private ArrayList<String> getSwitchDialogBodyList() {
+ ArrayList<String> list = new ArrayList<String>(mActiveSubInfos.stream()
+ .map(subInfo -> {
+ CharSequence subInfoName = SubscriptionUtil.getUniqueSubscriptionDisplayName(
+ subInfo, this);
+ return getString(
+ R.string.sim_action_switch_sub_dialog_carrier_list_item_for_turning_off,
+ subInfoName);
+ })
+ .collect(Collectors.toList()));
+ list.add(getString(R.string.sim_action_cancel));
+ return list;
+ }
+
private boolean isDsdsConditionSatisfied() {
if (mTelMgr.isMultiSimEnabled()) {
Log.i(TAG, "DSDS is already enabled. Condition not satisfied.");
@@ -477,17 +565,7 @@
Log.i(TAG, "Hardware does not support DSDS.");
return false;
}
- ImmutableList<UiccSlotInfo> slotInfos = UiccSlotUtil.getSlotInfos(mTelMgr);
- boolean isRemovableSimEnabled =
- slotInfos.stream()
- .anyMatch(
- slot ->
- slot != null
- && slot.isRemovable()
- && slot.getPorts().stream().anyMatch(
- port -> port.isActive())
- && slot.getCardStateInfo()
- == UiccSlotInfo.CARD_STATE_INFO_PRESENT);
+ boolean isRemovableSimEnabled = isRemovableSimEnabled();
if (mIsEsimOperation && isRemovableSimEnabled) {
Log.i(TAG, "eSIM operation and removable SIM is enabled. DSDS condition satisfied.");
return true;
@@ -496,13 +574,36 @@
SubscriptionUtil.getActiveSubscriptions(mSubscriptionManager).stream()
.anyMatch(SubscriptionInfo::isEmbedded);
if (!mIsEsimOperation && isEsimProfileEnabled) {
- Log.i(
- TAG,
- "Removable SIM operation and eSIM profile is enabled. DSDS condition"
- + " satisfied.");
+ Log.i(TAG, "Removable SIM operation and eSIM profile is enabled. DSDS condition"
+ + " satisfied.");
return true;
}
Log.i(TAG, "DSDS condition not satisfied.");
return false;
}
+
+ private boolean isRemovableSimEnabled() {
+ ImmutableList<UiccSlotInfo> slotInfos = UiccSlotUtil.getSlotInfos(mTelMgr);
+ boolean isRemovableSimEnabled =
+ slotInfos.stream()
+ .anyMatch(
+ slot -> slot != null
+ && slot.isRemovable()
+ && slot.getPorts().stream().anyMatch(
+ port -> port.isActive())
+ && slot.getCardStateInfo()
+ == UiccSlotInfo.CARD_STATE_INFO_PRESENT);
+ Log.i(TAG, "isRemovableSimEnabled: " + isRemovableSimEnabled);
+ return isRemovableSimEnabled;
+ }
+
+ private boolean isMultipleEnabledProfilesSupported() {
+ List<UiccCardInfo> cardInfos = mTelMgr.getUiccCardsInfo();
+ if (cardInfos == null) {
+ Log.w(TAG, "UICC cards info list is empty.");
+ return false;
+ }
+ return cardInfos.stream().anyMatch(
+ cardInfo -> cardInfo.isMultipleEnabledProfilesSupported());
+ }
}
diff --git a/src/com/android/settings/network/telephony/gsm/AutoSelectPreferenceController.java b/src/com/android/settings/network/telephony/gsm/AutoSelectPreferenceController.java
index 997235c..028c4e7 100644
--- a/src/com/android/settings/network/telephony/gsm/AutoSelectPreferenceController.java
+++ b/src/com/android/settings/network/telephony/gsm/AutoSelectPreferenceController.java
@@ -20,9 +20,8 @@
import static androidx.lifecycle.Lifecycle.Event.ON_STOP;
import android.app.ProgressDialog;
-import android.app.settings.SettingsEnums;
import android.content.Context;
-import android.os.Bundle;
+import android.content.Intent;
import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.Looper;
@@ -43,10 +42,8 @@
import androidx.preference.SwitchPreference;
import com.android.settings.R;
-import com.android.settings.core.SubSettingLauncher;
import com.android.settings.network.AllowedNetworkTypesListener;
import com.android.settings.network.telephony.MobileNetworkUtils;
-import com.android.settings.network.telephony.NetworkSelectSettings;
import com.android.settings.network.telephony.TelephonyTogglePreferenceController;
import com.android.settingslib.utils.ThreadUtils;
@@ -151,25 +148,26 @@
public boolean setChecked(boolean isChecked) {
if (isChecked) {
setAutomaticSelectionMode();
- return false;
} else {
- final Bundle bundle = new Bundle();
- bundle.putInt(Settings.EXTRA_SUB_ID, mSubId);
- new SubSettingLauncher(mContext)
- .setDestination(NetworkSelectSettings.class.getName())
- .setSourceMetricsCategory(SettingsEnums.MOBILE_NETWORK_SELECT)
- .setTitleRes(R.string.choose_network_title)
- .setArguments(bundle)
- .launch();
- return false;
+ if (mSwitchPreference != null) {
+ Intent intent = new Intent();
+ intent.setClassName("com.android.settings",
+ "com.android.settings.Settings$NetworkSelectActivity");
+ intent.putExtra(Settings.EXTRA_SUB_ID, mSubId);
+ mSwitchPreference.setIntent(intent);
+ }
}
+ return false;
}
@VisibleForTesting
Future setAutomaticSelectionMode() {
final long startMillis = SystemClock.elapsedRealtime();
showAutoSelectProgressBar();
- mSwitchPreference.setEnabled(false);
+ if (mSwitchPreference != null) {
+ mSwitchPreference.setIntent(null);
+ mSwitchPreference.setEnabled(false);
+ }
return ThreadUtils.postOnBackgroundThread(() -> {
// set network selection mode in background
mTelephonyManager.setNetworkSelectionModeAutomatic();
diff --git a/src/com/android/settings/network/telephony/gsm/OpenNetworkSelectPagePreferenceController.java b/src/com/android/settings/network/telephony/gsm/OpenNetworkSelectPagePreferenceController.java
index 4047009..54f5ce1 100644
--- a/src/com/android/settings/network/telephony/gsm/OpenNetworkSelectPagePreferenceController.java
+++ b/src/com/android/settings/network/telephony/gsm/OpenNetworkSelectPagePreferenceController.java
@@ -19,14 +19,12 @@
import static androidx.lifecycle.Lifecycle.Event.ON_START;
import static androidx.lifecycle.Lifecycle.Event.ON_STOP;
-import android.app.settings.SettingsEnums;
import android.content.Context;
-import android.os.Bundle;
+import android.content.Intent;
import android.provider.Settings;
import android.telephony.ServiceState;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
-import android.text.TextUtils;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
@@ -35,10 +33,8 @@
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
-import com.android.settings.core.SubSettingLauncher;
import com.android.settings.network.AllowedNetworkTypesListener;
import com.android.settings.network.telephony.MobileNetworkUtils;
-import com.android.settings.network.telephony.NetworkSelectSettings;
import com.android.settings.network.telephony.TelephonyBasePreferenceController;
/**
@@ -102,6 +98,12 @@
super.updateState(preference);
preference.setEnabled(mTelephonyManager.getNetworkSelectionMode()
!= TelephonyManager.NETWORK_SELECTION_MODE_AUTO);
+
+ Intent intent = new Intent();
+ intent.setClassName("com.android.settings",
+ "com.android.settings.Settings$NetworkSelectActivity");
+ intent.putExtra(Settings.EXTRA_SUB_ID, mSubId);
+ preference.setIntent(intent);
}
@Override
@@ -114,23 +116,6 @@
}
}
- @Override
- public boolean handlePreferenceTreeClick(Preference preference) {
- if (TextUtils.equals(preference.getKey(), getPreferenceKey())) {
- final Bundle bundle = new Bundle();
- bundle.putInt(Settings.EXTRA_SUB_ID, mSubId);
- new SubSettingLauncher(mContext)
- .setDestination(NetworkSelectSettings.class.getName())
- .setSourceMetricsCategory(SettingsEnums.MOBILE_NETWORK_SELECT)
- .setTitleRes(R.string.choose_network_title)
- .setArguments(bundle)
- .launch();
- return true;
- }
-
- return false;
- }
-
public OpenNetworkSelectPagePreferenceController init(Lifecycle lifecycle, int subId) {
mSubId = subId;
mTelephonyManager = mContext.getSystemService(TelephonyManager.class)
diff --git a/src/com/android/settings/password/ChooseLockPassword.java b/src/com/android/settings/password/ChooseLockPassword.java
index c033625..a2f9922 100644
--- a/src/com/android/settings/password/ChooseLockPassword.java
+++ b/src/com/android/settings/password/ChooseLockPassword.java
@@ -268,9 +268,7 @@
R.string.lockpassword_choose_your_pin_header_for_fingerprint,
R.string.lockpassword_choose_your_pin_header_for_face,
R.string.lockpassword_choose_your_pin_header_for_biometrics,
- R.string.lockpassword_choose_password_description,
R.string.lock_settings_picker_biometrics_added_security_message,
- R.string.lockpassword_choose_pin_description,
R.string.lock_settings_picker_biometrics_added_security_message,
R.string.next_label),
@@ -287,8 +285,6 @@
R.string.lockpassword_confirm_your_pin_header,
0,
0,
- 0,
- 0,
R.string.lockpassword_confirm_label),
ConfirmWrong(
@@ -304,8 +300,6 @@
R.string.lockpassword_confirm_pins_dont_match,
0,
0,
- 0,
- 0,
R.string.lockpassword_confirm_label);
Stage(int hintInAlpha,
@@ -318,9 +312,7 @@
int hintInNumericForFingerprint,
int hintInNumericForFace,
int hintInNumericForBiometrics,
- int messageInAlpha,
int messageInAlphaForBiometrics,
- int messageInNumeric,
int messageInNumericForBiometrics,
int nextButtonText) {
@@ -336,10 +328,7 @@
this.numericHintForFace = hintInNumericForFace;
this.numericHintForBiometrics = hintInNumericForBiometrics;
- this.alphaMessage = messageInAlpha;
this.alphaMessageForBiometrics = messageInAlphaForBiometrics;
-
- this.numericMessage = messageInNumeric;
this.numericMessageForBiometrics = messageInNumericForBiometrics;
this.buttonText = nextButtonText;
@@ -365,11 +354,9 @@
public final int numericHintForBiometrics;
// Password description
- public final int alphaMessage;
public final int alphaMessageForBiometrics;
// PIN description
- public final int numericMessage;
public final int numericMessageForBiometrics;
public final int buttonText;
@@ -407,7 +394,7 @@
case TYPE_NONE:
default:
- return isAlpha ? alphaMessage : numericMessage;
+ return 0;
}
}
}
@@ -869,12 +856,17 @@
setNextEnabled(canInput && length >= LockPatternUtils.MIN_LOCK_PASSWORD_SIZE);
mSkipOrClearButton.setVisibility(toVisibility(canInput && length > 0));
}
- int message = mUiStage.getMessage(mIsAlphaMode, getStageType());
- if (message != 0) {
- mMessage.setVisibility(View.VISIBLE);
- mMessage.setText(message);
+ final int stage = getStageType();
+ if (getStageType() != Stage.TYPE_NONE) {
+ int message = mUiStage.getMessage(mIsAlphaMode, stage);
+ if (message != 0) {
+ mMessage.setVisibility(View.VISIBLE);
+ mMessage.setText(message);
+ } else {
+ mMessage.setVisibility(View.INVISIBLE);
+ }
} else {
- mMessage.setVisibility(View.INVISIBLE);
+ mMessage.setVisibility(View.GONE);
}
setNextText(mUiStage.buttonText);
diff --git a/src/com/android/settings/password/ChooseLockPattern.java b/src/com/android/settings/password/ChooseLockPattern.java
index 016906a..3e7622c 100644
--- a/src/com/android/settings/password/ChooseLockPattern.java
+++ b/src/com/android/settings/password/ChooseLockPattern.java
@@ -363,54 +363,49 @@
Introduction(
R.string.lock_settings_picker_biometrics_added_security_message,
- R.string.lockpattern_choose_pattern_description,
R.string.lockpattern_recording_intro_header,
LeftButtonMode.Gone, RightButtonMode.ContinueDisabled,
ID_EMPTY_MESSAGE, true),
HelpScreen(
- ID_EMPTY_MESSAGE, ID_EMPTY_MESSAGE, R.string.lockpattern_settings_help_how_to_record,
+ ID_EMPTY_MESSAGE, R.string.lockpattern_settings_help_how_to_record,
LeftButtonMode.Gone, RightButtonMode.Ok, ID_EMPTY_MESSAGE, false),
ChoiceTooShort(
R.string.lock_settings_picker_biometrics_added_security_message,
- R.string.lockpattern_choose_pattern_description,
R.string.lockpattern_recording_incorrect_too_short,
LeftButtonMode.Retry, RightButtonMode.ContinueDisabled,
ID_EMPTY_MESSAGE, true),
FirstChoiceValid(
R.string.lock_settings_picker_biometrics_added_security_message,
- R.string.lockpattern_choose_pattern_description,
R.string.lockpattern_pattern_entered_header,
LeftButtonMode.Retry, RightButtonMode.Continue, ID_EMPTY_MESSAGE, false),
NeedToConfirm(
- ID_EMPTY_MESSAGE, ID_EMPTY_MESSAGE, R.string.lockpattern_need_to_confirm,
+ ID_EMPTY_MESSAGE, R.string.lockpattern_need_to_confirm,
LeftButtonMode.Gone, RightButtonMode.ConfirmDisabled,
ID_EMPTY_MESSAGE, true),
ConfirmWrong(
- ID_EMPTY_MESSAGE, ID_EMPTY_MESSAGE, R.string.lockpattern_need_to_unlock_wrong,
+ ID_EMPTY_MESSAGE, R.string.lockpattern_need_to_unlock_wrong,
LeftButtonMode.Gone, RightButtonMode.ConfirmDisabled,
ID_EMPTY_MESSAGE, true),
ChoiceConfirmed(
- ID_EMPTY_MESSAGE, ID_EMPTY_MESSAGE, R.string.lockpattern_pattern_confirmed_header,
+ ID_EMPTY_MESSAGE, R.string.lockpattern_pattern_confirmed_header,
LeftButtonMode.Gone, RightButtonMode.Confirm, ID_EMPTY_MESSAGE, false);
/**
* @param messageForBiometrics The message displayed at the top, above header for
* fingerprint flow.
- * @param message The message displayed at the top.
* @param headerMessage The message displayed at the top.
* @param leftMode The mode of the left button.
* @param rightMode The mode of the right button.
* @param footerMessage The footer message.
* @param patternEnabled Whether the pattern widget is enabled.
*/
- Stage(int messageForBiometrics, int message, int headerMessage,
+ Stage(int messageForBiometrics, int headerMessage,
LeftButtonMode leftMode,
RightButtonMode rightMode,
int footerMessage, boolean patternEnabled) {
this.headerMessage = headerMessage;
this.messageForBiometrics = messageForBiometrics;
- this.message = message;
this.leftMode = leftMode;
this.rightMode = rightMode;
this.footerMessage = footerMessage;
@@ -419,7 +414,6 @@
final int headerMessage;
final int messageForBiometrics;
- final int message;
final LeftButtonMode leftMode;
final RightButtonMode rightMode;
final int footerMessage;
@@ -735,11 +729,14 @@
}
final GlifLayout layout = getActivity().findViewById(R.id.setup_wizard_layout);
final boolean forAnyBiometric = mForFingerprint || mForFace || mForBiometrics;
- int message = forAnyBiometric ? stage.messageForBiometrics : stage.message;
- if (message == ID_EMPTY_MESSAGE) {
- layout.setDescriptionText("");
+ if (forAnyBiometric) {
+ if (stage.messageForBiometrics == ID_EMPTY_MESSAGE) {
+ layout.setDescriptionText("");
+ } else {
+ layout.setDescriptionText(stage.messageForBiometrics);
+ }
} else {
- layout.setDescriptionText(message);
+ layout.getDescriptionTextView().setVisibility(View.GONE);
}
if (stage.footerMessage == ID_EMPTY_MESSAGE) {
mFooterText.setText("");
diff --git a/src/com/android/settings/password/OWNERS b/src/com/android/settings/password/OWNERS
index 636800f..3b2013b 100644
--- a/src/com/android/settings/password/OWNERS
+++ b/src/com/android/settings/password/OWNERS
@@ -1,5 +1,6 @@
# Default reviewers for this and subdirectories.
curtislb@google.com
+graciecheng@google.com
ilyamaty@google.com
jaggies@google.com
jbolinger@google.com
@@ -8,4 +9,4 @@
paulcrowley@google.com
rubinxu@google.com
-# Emergency approvers in case the above are not available
\ No newline at end of file
+# Emergency approvers in case the above are not available
diff --git a/src/com/android/settings/password/SetupChooseLockPattern.java b/src/com/android/settings/password/SetupChooseLockPattern.java
index 70cd6f2..7151c6d 100644
--- a/src/com/android/settings/password/SetupChooseLockPattern.java
+++ b/src/com/android/settings/password/SetupChooseLockPattern.java
@@ -142,14 +142,8 @@
mLeftButtonIsSkip = false;
}
- // Show generic pattern message when pattern lock screen launch in Setup wizard flow
- // before fingerprint and face setup.
final GlifLayout layout = getActivity().findViewById(R.id.setup_wizard_layout);
- if (stage.message == ID_EMPTY_MESSAGE) {
- layout.setDescriptionText("");
- } else {
- layout.setDescriptionText(stage.message);
- }
+ layout.setDescriptionText("");
}
@Override
diff --git a/src/com/android/settings/search/SearchResultTrampoline.java b/src/com/android/settings/search/SearchResultTrampoline.java
index f9cbc36..8b041b6 100644
--- a/src/com/android/settings/search/SearchResultTrampoline.java
+++ b/src/com/android/settings/search/SearchResultTrampoline.java
@@ -109,7 +109,8 @@
final SettingsHomepageActivity homeActivity =
((SettingsApplication) getApplicationContext()).getHomeActivity();
if (homeActivity != null) {
- homeActivity.getMainFragment().setHighlightMenuKey(highlightMenuKey);
+ homeActivity.getMainFragment().setHighlightMenuKey(highlightMenuKey,
+ /* scrollNeeded= */ true);
}
} else {
// Two-pane case
diff --git a/src/com/android/settings/security/InstallCaCertificateWarning.java b/src/com/android/settings/security/InstallCaCertificateWarning.java
index 3854875..139bc1c 100644
--- a/src/com/android/settings/security/InstallCaCertificateWarning.java
+++ b/src/com/android/settings/security/InstallCaCertificateWarning.java
@@ -16,6 +16,8 @@
package com.android.settings.security;
+import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
+
import android.annotation.Nullable;
import android.app.Activity;
import android.content.Intent;
@@ -45,6 +47,8 @@
setTheme(SetupWizardUtils.getTheme(this, getIntent()));
ThemeHelper.trySetDynamicColor(this);
setContentView(R.layout.ca_certificate_warning_dialog);
+ getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
+
final GlifLayout layout = findViewById(R.id.setup_wizard_layout);
layout.setHeaderText(R.string.ca_certificate_warning_title);
@@ -57,6 +61,7 @@
.setTheme(R.style.SudGlifButton_Secondary)
.build()
);
+ mixin.getSecondaryButtonView().setFilterTouchesWhenObscured(true);
mixin.setPrimaryButton(
new FooterButton.Builder(this)
@@ -66,6 +71,7 @@
.setTheme(R.style.SudGlifButton_Primary)
.build()
);
+ mixin.getPrimaryButtonView().setFilterTouchesWhenObscured(true);
}
private View.OnClickListener installCaCertificate() {
diff --git a/src/com/android/settings/sim/DsdsDialogActivity.java b/src/com/android/settings/sim/DsdsDialogActivity.java
index 62a6995..7d9a43b 100644
--- a/src/com/android/settings/sim/DsdsDialogActivity.java
+++ b/src/com/android/settings/sim/DsdsDialogActivity.java
@@ -85,7 +85,7 @@
}
@Override
- public void onConfirm(int tag, boolean confirmed) {
+ public void onConfirm(int tag, boolean confirmed, int itemPosition) {
if (!confirmed) {
Log.i(TAG, "User cancel the dialog to enable DSDS.");
startChooseSimActivity();
diff --git a/src/com/android/settings/sim/SimDialogActivity.java b/src/com/android/settings/sim/SimDialogActivity.java
index e5457ae..f9aca77 100644
--- a/src/com/android/settings/sim/SimDialogActivity.java
+++ b/src/com/android/settings/sim/SimDialogActivity.java
@@ -160,8 +160,10 @@
final TelephonyManager telephonyManager = getSystemService(
TelephonyManager.class).createForSubscriptionId(subId);
subscriptionManager.setDefaultDataSubId(subId);
- telephonyManager.setDataEnabled(true);
- Toast.makeText(this, R.string.data_switch_started, Toast.LENGTH_LONG).show();
+ if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ telephonyManager.setDataEnabled(true);
+ Toast.makeText(this, R.string.data_switch_started, Toast.LENGTH_LONG).show();
+ }
}
private void setDefaultCallsSubId(final int subId) {
diff --git a/src/com/android/settings/sim/SwitchToEsimConfirmDialogActivity.java b/src/com/android/settings/sim/SwitchToEsimConfirmDialogActivity.java
index 385deff..be2fa2d 100644
--- a/src/com/android/settings/sim/SwitchToEsimConfirmDialogActivity.java
+++ b/src/com/android/settings/sim/SwitchToEsimConfirmDialogActivity.java
@@ -101,7 +101,7 @@
}
@Override
- public void onConfirm(int tag, boolean confirmed) {
+ public void onConfirm(int tag, boolean confirmed, int itemPosition) {
if (!confirmed) {
AlertDialogFragment.show(
this,
diff --git a/src/com/android/settings/widget/HighlightableTopLevelPreferenceAdapter.java b/src/com/android/settings/widget/HighlightableTopLevelPreferenceAdapter.java
index b7f3015..ff8f805 100644
--- a/src/com/android/settings/widget/HighlightableTopLevelPreferenceAdapter.java
+++ b/src/com/android/settings/widget/HighlightableTopLevelPreferenceAdapter.java
@@ -20,6 +20,7 @@
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.Log;
+import android.util.SparseArray;
import android.util.TypedValue;
import android.view.View;
import android.widget.ImageView;
@@ -59,17 +60,18 @@
private final int mNormalBackgroundRes;
private final int mHighlightBackgroundRes;
private String mHighlightKey;
- private String mPreviousHighlightKey;
private int mHighlightPosition = RecyclerView.NO_POSITION;
private int mScrollPosition = RecyclerView.NO_POSITION;
private boolean mHighlightNeeded;
private boolean mScrolled;
+ private SparseArray<PreferenceViewHolder> mViewHolders;
public HighlightableTopLevelPreferenceAdapter(SettingsHomepageActivity homepageActivity,
PreferenceGroup preferenceGroup, RecyclerView recyclerView, String key) {
super(preferenceGroup);
mRecyclerView = recyclerView;
mHighlightKey = key;
+ mViewHolders = new SparseArray<>();
mContext = preferenceGroup.getContext();
mHomepageActivity = homepageActivity;
final TypedValue outValue = new TypedValue();
@@ -92,6 +94,7 @@
@Override
public void onBindViewHolder(PreferenceViewHolder holder, int position) {
super.onBindViewHolder(holder, position);
+ mViewHolders.put(position, holder);
updateBackground(holder, position);
}
@@ -120,9 +123,9 @@
return;
}
+ final int previousPosition = mHighlightPosition;
if (TextUtils.isEmpty(mHighlightKey)) {
// De-highlight previous preference.
- final int previousPosition = mHighlightPosition;
mHighlightPosition = RecyclerView.NO_POSITION;
mScrolled = true;
if (previousPosition >= 0) {
@@ -145,10 +148,14 @@
// Turn on/off highlight when screen split mode is changed.
if (highlightNeeded != mHighlightNeeded) {
- Log.d(TAG, "Highlight change needed: " + highlightNeeded);
+ Log.d(TAG, "Highlight needed change: " + highlightNeeded);
mHighlightNeeded = highlightNeeded;
mHighlightPosition = position;
notifyItemChanged(position);
+ if (!highlightNeeded) {
+ // De-highlight to prevent a flicker
+ removeHighlightAt(previousPosition);
+ }
return;
}
@@ -156,7 +163,6 @@
return;
}
- final int previousPosition = mHighlightPosition;
mHighlightPosition = position;
Log.d(TAG, "Request highlight position " + position);
Log.d(TAG, "Is highlight needed: " + highlightNeeded);
@@ -178,20 +184,11 @@
* preference is clicked.
*/
public void highlightPreference(String key, boolean scrollNeeded) {
- mPreviousHighlightKey = mHighlightKey;
mHighlightKey = key;
mScrolled = !scrollNeeded;
requestHighlight();
}
- /**
- * A function that restores the previous highlighted setting.
- */
- public void restorePreviousHighlight() {
- mHighlightKey = mPreviousHighlightKey;
- requestHighlight();
- }
-
@Override
public void onHomepageLoaded() {
scroll();
@@ -224,6 +221,17 @@
}
}
+ private void removeHighlightAt(int position) {
+ if (position >= 0) {
+ // De-highlight the existing preference view holder at an early stage
+ final PreferenceViewHolder holder = mViewHolders.get(position);
+ if (holder != null) {
+ removeHighlightBackground(holder);
+ }
+ notifyItemChanged(position);
+ }
+ }
+
private void addHighlightBackground(PreferenceViewHolder holder) {
final View v = holder.itemView;
v.setBackgroundResource(mHighlightBackgroundRes);
diff --git a/src/com/android/settings/wifi/WifiConfigController.java b/src/com/android/settings/wifi/WifiConfigController.java
index 408ffbe..0c063db 100644
--- a/src/com/android/settings/wifi/WifiConfigController.java
+++ b/src/com/android/settings/wifi/WifiConfigController.java
@@ -1503,11 +1503,15 @@
}
// Shows display name of each active subscription.
- final String[] displayNames = SubscriptionUtil.getUniqueSubscriptionDisplayNames(
- mContext).values().stream().toArray(String[]::new);
- mEapSimSpinner.setAdapter(getSpinnerAdapter(displayNames));
+ final ArrayList<CharSequence> displayNames = new ArrayList<>();
+ for (SubscriptionInfo activeSubInfo : mActiveSubscriptionInfos) {
+ displayNames.add(
+ SubscriptionUtil.getUniqueSubscriptionDisplayName(activeSubInfo, mContext));
+ }
+ mEapSimSpinner.setAdapter(
+ getSpinnerAdapter(displayNames.toArray(new String[displayNames.size()])));
mEapSimSpinner.setSelection(0 /* position */);
- if (displayNames.length == 1) {
+ if (displayNames.size() == 1) {
mEapSimSpinner.setEnabled(false);
}
}
diff --git a/src/com/android/settings/wifi/WifiConfigController2.java b/src/com/android/settings/wifi/WifiConfigController2.java
index 011c970..127c882 100644
--- a/src/com/android/settings/wifi/WifiConfigController2.java
+++ b/src/com/android/settings/wifi/WifiConfigController2.java
@@ -1482,11 +1482,15 @@
}
// Shows display name of each active subscription.
- final String[] displayNames = SubscriptionUtil.getUniqueSubscriptionDisplayNames(
- mContext).values().stream().toArray(String[]::new);
- mEapSimSpinner.setAdapter(getSpinnerAdapter(displayNames));
+ final ArrayList<CharSequence> displayNames = new ArrayList<>();
+ for (SubscriptionInfo activeSubInfo : mActiveSubscriptionInfos) {
+ displayNames.add(
+ SubscriptionUtil.getUniqueSubscriptionDisplayName(activeSubInfo, mContext));
+ }
+ mEapSimSpinner.setAdapter(
+ getSpinnerAdapter(displayNames.toArray(new String[displayNames.size()])));
mEapSimSpinner.setSelection(0 /* position */);
- if (displayNames.length == 1) {
+ if (displayNames.size() == 1) {
mEapSimSpinner.setEnabled(false);
}
}
diff --git a/src/com/android/settings/wifi/calling/LinkifyDescriptionPreference.java b/src/com/android/settings/wifi/calling/LinkifyDescriptionPreference.java
new file mode 100644
index 0000000..60400b0
--- /dev/null
+++ b/src/com/android/settings/wifi/calling/LinkifyDescriptionPreference.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package com.android.settings.wifi.calling;
+
+import android.content.Context;
+import android.text.SpannableString;
+import android.text.TextUtils;
+import android.text.method.LinkMovementMethod;
+import android.text.style.ClickableSpan;
+import android.text.util.Linkify;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.TextView;
+
+import androidx.core.text.util.LinkifyCompat;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceViewHolder;
+
+import com.android.settings.R;
+
+/** A preference which supports linkify text as a description in the summary **/
+public class LinkifyDescriptionPreference extends Preference {
+
+ public LinkifyDescriptionPreference(Context context) {
+ this(context, null);
+ }
+
+ public LinkifyDescriptionPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder holder) {
+ super.onBindViewHolder(holder);
+
+ final TextView summaryView = (TextView) holder.findViewById(android.R.id.summary);
+ if (summaryView == null || summaryView.getVisibility() != View.VISIBLE) {
+ return;
+ }
+
+ final CharSequence summary = getSummary();
+ if (TextUtils.isEmpty(summary)) {
+ return;
+ }
+
+ summaryView.setMaxLines(Integer.MAX_VALUE);
+
+ final SpannableString spannableSummary = new SpannableString(summary);
+ if (spannableSummary.getSpans(0, spannableSummary.length(), ClickableSpan.class)
+ .length > 0) {
+ summaryView.setMovementMethod(LinkMovementMethod.getInstance());
+ }
+ LinkifyCompat.addLinks(summaryView,
+ Linkify.WEB_URLS | Linkify.EMAIL_ADDRESSES | Linkify.PHONE_NUMBERS);
+ }
+}
diff --git a/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java b/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java
index 53e1b4c..19664be 100644
--- a/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java
+++ b/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java
@@ -35,9 +35,7 @@
import android.telephony.ims.ImsMmTelManager;
import android.telephony.ims.ProvisioningManager;
import android.text.TextUtils;
-import android.text.util.Linkify;
import android.util.Log;
-import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -59,8 +57,11 @@
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.network.ims.WifiCallingQueryImsState;
import com.android.settings.widget.SettingsMainSwitchBar;
+import com.android.settings.wifi.calling.LinkifyDescriptionPreference;
import com.android.settingslib.widget.OnMainSwitchChangeListener;
+import java.util.List;
+
/**
* This is the inner class of {@link WifiCallingSettings} fragment.
* The preference screen lets you enable/disable Wi-Fi Calling and change Wi-Fi Calling mode.
@@ -74,6 +75,7 @@
private static final String BUTTON_WFC_MODE = "wifi_calling_mode";
private static final String BUTTON_WFC_ROAMING_MODE = "wifi_calling_roaming_mode";
private static final String PREFERENCE_EMERGENCY_ADDRESS = "emergency_address_key";
+ private static final String PREFERENCE_NO_OPTIONS_DESC = "no_options_description";
@VisibleForTesting
static final int REQUEST_CHECK_WFC_EMERGENCY_ADDRESS = 1;
@@ -93,7 +95,6 @@
private ListWithEntrySummaryPreference mButtonWfcMode;
private ListWithEntrySummaryPreference mButtonWfcRoamingMode;
private Preference mUpdateAddress;
- private TextView mEmptyView;
private boolean mValidListener = false;
private boolean mEditableWfcMode = true;
@@ -187,15 +188,6 @@
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
- mEmptyView = getView().findViewById(android.R.id.empty);
- setEmptyView(mEmptyView);
- mEmptyView.setAutoLinkMask(Linkify.WEB_URLS);
- final Resources res = getResourcesForSubId();
- final String emptyViewText = res.getString(R.string.wifi_calling_off_explanation,
- res.getString(R.string.wifi_calling_off_explanation_2));
- mEmptyView.setText(emptyViewText);
- mEmptyView.setGravity(Gravity.TOP | Gravity.LEFT);
-
mSwitchBar = getView().findViewById(R.id.switch_bar);
mSwitchBar.show();
}
@@ -311,6 +303,9 @@
mIntentFilter = new IntentFilter();
mIntentFilter.addAction(ImsManager.ACTION_WFC_IMS_REGISTRATION_ERROR);
+
+ updateDescriptionForOptions(
+ List.of(mButtonWfcMode, mButtonWfcRoamingMode, mUpdateAddress));
}
@Override
@@ -326,7 +321,7 @@
final View view = inflater.inflate(
R.layout.wifi_calling_settings_preferences, container, false);
- final ViewGroup prefs_container = view.findViewById(R.id.prefs_container);
+ final ViewGroup prefs_container = view.findViewById(android.R.id.tabcontent);
Utils.prepareCustomPreferencesList(container, view, prefs_container, false);
final View prefs = super.onCreateView(inflater, prefs_container, savedInstanceState);
prefs_container.addView(prefs);
@@ -575,28 +570,35 @@
final PreferenceScreen preferenceScreen = getPreferenceScreen();
final boolean updateAddressEnabled = (getCarrierActivityIntent() != null);
if (wfcEnabled) {
- if (mEditableWfcMode) {
- preferenceScreen.addPreference(mButtonWfcMode);
- } else {
- // Don't show WFC (home) preference if it's not editable.
- preferenceScreen.removePreference(mButtonWfcMode);
- }
- if (mEditableWfcRoamingMode && !mUseWfcHomeModeForRoaming) {
- preferenceScreen.addPreference(mButtonWfcRoamingMode);
- } else {
- // Don't show WFC roaming preference if it's not editable.
- preferenceScreen.removePreference(mButtonWfcRoamingMode);
- }
- if (updateAddressEnabled) {
- preferenceScreen.addPreference(mUpdateAddress);
- } else {
- preferenceScreen.removePreference(mUpdateAddress);
- }
+ // Don't show WFC (home) preference if it's not editable.
+ mButtonWfcMode.setVisible(mEditableWfcMode);
+ // Don't show WFC roaming preference if it's not editable.
+ mButtonWfcRoamingMode.setVisible(
+ mEditableWfcRoamingMode && !mUseWfcHomeModeForRoaming);
+ mUpdateAddress.setVisible(updateAddressEnabled);
} else {
- preferenceScreen.removePreference(mButtonWfcMode);
- preferenceScreen.removePreference(mButtonWfcRoamingMode);
- preferenceScreen.removePreference(mUpdateAddress);
+ mButtonWfcMode.setVisible(false);
+ mButtonWfcRoamingMode.setVisible(false);
+ mUpdateAddress.setVisible(false);
}
+ updateDescriptionForOptions(
+ List.of(mButtonWfcMode, mButtonWfcRoamingMode, mUpdateAddress));
+ }
+
+ private void updateDescriptionForOptions(List<Preference> visibleOptions) {
+ LinkifyDescriptionPreference pref = findPreference(PREFERENCE_NO_OPTIONS_DESC);
+ if (pref == null) {
+ return;
+ }
+
+ boolean optionsAvailable = visibleOptions.stream().anyMatch(Preference::isVisible);
+ if (!optionsAvailable) {
+ final Resources res = getResourcesForSubId();
+ String emptyViewText = res.getString(R.string.wifi_calling_off_explanation,
+ res.getString(R.string.wifi_calling_off_explanation_2));
+ pref.setSummary(emptyViewText);
+ }
+ pref.setVisible(!optionsAvailable);
}
@Override
diff --git a/tests/robotests/src/com/android/settings/development/bluetooth/AbstractBluetoothDialogPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/bluetooth/AbstractBluetoothDialogPreferenceControllerTest.java
index a12131d..c1648bf 100644
--- a/tests/robotests/src/com/android/settings/development/bluetooth/AbstractBluetoothDialogPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/bluetooth/AbstractBluetoothDialogPreferenceControllerTest.java
@@ -47,6 +47,7 @@
import org.robolectric.RuntimeEnvironment;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
@RunWith(RobolectricTestRunner.class)
@@ -85,8 +86,12 @@
mBluetoothA2dpConfigStore));
mPreference = spy(new BaseBluetoothDialogPreferenceImpl(mContext));
- mCodecConfigAAC = new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC);
- mCodecConfigSBC = new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC);
+ mCodecConfigAAC = new BluetoothCodecConfig.Builder()
+ .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC)
+ .build();
+ mCodecConfigSBC = new BluetoothCodecConfig.Builder()
+ .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC)
+ .build();
mCodecConfigs[0] = mCodecConfigAAC;
mCodecConfigs[1] = mCodecConfigSBC;
@@ -160,17 +165,19 @@
@Test
public void getSelectableConfigs_verifyConfig() {
- mCodecStatus = new BluetoothCodecStatus(mCodecConfigAAC, null, mCodecConfigs);
+ mCodecStatus = new BluetoothCodecStatus(mCodecConfigAAC, null,
+ Arrays.asList(mCodecConfigs));
when(mBluetoothA2dp.getCodecStatus(
mActiveDevice)).thenReturn(mCodecStatus);
mController.onBluetoothServiceConnected(mBluetoothA2dp);
- assertThat(mController.getSelectableConfigs(null)).isEqualTo(mCodecConfigs);
+ assertThat(mController.getSelectableConfigs(null)).isEqualTo(Arrays.asList(mCodecConfigs));
}
@Test
public void getSelectableByCodecType_verifyConfig() {
- mCodecStatus = new BluetoothCodecStatus(mCodecConfigAAC, null, mCodecConfigs);
+ mCodecStatus = new BluetoothCodecStatus(mCodecConfigAAC, null,
+ Arrays.asList(mCodecConfigs));
when(mBluetoothA2dp.getCodecStatus(
mActiveDevice)).thenReturn(mCodecStatus);
mController.onBluetoothServiceConnected(mBluetoothA2dp);
@@ -181,7 +188,8 @@
@Test
public void getSelectableByCodecType_unavailable() {
- mCodecStatus = new BluetoothCodecStatus(mCodecConfigAAC, null, mCodecConfigs);
+ mCodecStatus = new BluetoothCodecStatus(mCodecConfigAAC, null,
+ Arrays.asList(mCodecConfigs));
when(mBluetoothA2dp.getCodecStatus(
mActiveDevice)).thenReturn(mCodecStatus);
mController.onBluetoothServiceConnected(mBluetoothA2dp);
@@ -192,7 +200,8 @@
@Test
public void onBluetoothServiceConnected_verifyBluetoothA2dpConfigStore() {
- mCodecStatus = new BluetoothCodecStatus(mCodecConfigAAC, null, mCodecConfigs);
+ mCodecStatus = new BluetoothCodecStatus(mCodecConfigAAC, null,
+ Arrays.asList(mCodecConfigs));
when(mBluetoothA2dp.getCodecStatus(
mActiveDevice)).thenReturn(mCodecStatus);
mController.onBluetoothServiceConnected(mBluetoothA2dp);
diff --git a/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothBitPerSampleDialogPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothBitPerSampleDialogPreferenceControllerTest.java
index 0996ae3..a042ebe 100644
--- a/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothBitPerSampleDialogPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothBitPerSampleDialogPreferenceControllerTest.java
@@ -44,6 +44,7 @@
import org.robolectric.RuntimeEnvironment;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
@RunWith(RobolectricTestRunner.class)
@@ -80,25 +81,23 @@
mPreference = new BluetoothBitPerSampleDialogPreference(mContext);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
mController.displayPreference(mScreen);
- mCodecConfigAAC = new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC,
- BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
- BluetoothCodecConfig.SAMPLE_RATE_NONE,
- BluetoothCodecConfig.BITS_PER_SAMPLE_16 | BluetoothCodecConfig.BITS_PER_SAMPLE_24,
- BluetoothCodecConfig.CHANNEL_MODE_NONE,
- 0, 0, 0, 0);
- mCodecConfigSBC = new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
- BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
- BluetoothCodecConfig.SAMPLE_RATE_NONE,
- BluetoothCodecConfig.BITS_PER_SAMPLE_24,
- BluetoothCodecConfig.CHANNEL_MODE_NONE,
- 0, 0, 0, 0);
+ mCodecConfigAAC = new BluetoothCodecConfig.Builder()
+ .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC)
+ .setBitsPerSample(BluetoothCodecConfig.BITS_PER_SAMPLE_16
+ | BluetoothCodecConfig.BITS_PER_SAMPLE_24)
+ .build();
+ mCodecConfigSBC = new BluetoothCodecConfig.Builder()
+ .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC)
+ .setBitsPerSample(BluetoothCodecConfig.BITS_PER_SAMPLE_24)
+ .build();
when(mBluetoothA2dp.getActiveDevice()).thenReturn(mActiveDevice);
}
@Test
public void writeConfigurationValues_selectDefault_setHighest() {
BluetoothCodecConfig[] mCodecConfigs = {mCodecConfigAAC, mCodecConfigSBC};
- mCodecStatus = new BluetoothCodecStatus(mCodecConfigAAC, null, mCodecConfigs);
+ mCodecStatus = new BluetoothCodecStatus(mCodecConfigAAC, null,
+ Arrays.asList(mCodecConfigs));
when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus);
mController.onBluetoothServiceConnected(mBluetoothA2dp);
@@ -127,7 +126,8 @@
@Test
public void getSelectableIndex_verifyList() {
BluetoothCodecConfig[] mCodecConfigs = {mCodecConfigAAC, mCodecConfigSBC};
- mCodecStatus = new BluetoothCodecStatus(mCodecConfigAAC, null, mCodecConfigs);
+ mCodecStatus = new BluetoothCodecStatus(mCodecConfigAAC, null,
+ Arrays.asList(mCodecConfigs));
when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus);
mController.onBluetoothServiceConnected(mBluetoothA2dp);
List<Integer> indexList = new ArrayList<>();
diff --git a/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothChannelModeDialogPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothChannelModeDialogPreferenceControllerTest.java
index 81fb3fe..75d8fc4 100644
--- a/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothChannelModeDialogPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothChannelModeDialogPreferenceControllerTest.java
@@ -44,6 +44,7 @@
import org.robolectric.RuntimeEnvironment;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
@RunWith(RobolectricTestRunner.class)
@@ -80,25 +81,23 @@
mPreference = new BluetoothChannelModeDialogPreference(mContext);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
mController.displayPreference(mScreen);
- mCodecConfigAAC = new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC,
- BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
- BluetoothCodecConfig.SAMPLE_RATE_NONE,
- BluetoothCodecConfig.BITS_PER_SAMPLE_NONE,
- BluetoothCodecConfig.CHANNEL_MODE_STEREO,
- 0, 0, 0, 0);
- mCodecConfigSBC = new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
- BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
- BluetoothCodecConfig.SAMPLE_RATE_NONE,
- BluetoothCodecConfig.BITS_PER_SAMPLE_NONE,
- BluetoothCodecConfig.CHANNEL_MODE_MONO | BluetoothCodecConfig.CHANNEL_MODE_STEREO,
- 0, 0, 0, 0);
+ mCodecConfigAAC = new BluetoothCodecConfig.Builder()
+ .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC)
+ .setChannelMode(BluetoothCodecConfig.CHANNEL_MODE_STEREO)
+ .build();
+ mCodecConfigSBC = new BluetoothCodecConfig.Builder()
+ .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC)
+ .setChannelMode(BluetoothCodecConfig.CHANNEL_MODE_MONO
+ | BluetoothCodecConfig.CHANNEL_MODE_STEREO)
+ .build();
when(mBluetoothA2dp.getActiveDevice()).thenReturn(mActiveDevice);
}
@Test
public void writeConfigurationValues_selectDefault_setHighest() {
BluetoothCodecConfig[] mCodecConfigs = {mCodecConfigAAC, mCodecConfigSBC};
- mCodecStatus = new BluetoothCodecStatus(mCodecConfigSBC, null, mCodecConfigs);
+ mCodecStatus = new BluetoothCodecStatus(mCodecConfigSBC, null,
+ Arrays.asList(mCodecConfigs));
when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus);
mController.onBluetoothServiceConnected(mBluetoothA2dp);
@@ -124,7 +123,8 @@
@Test
public void getSelectableIndex_verifyList() {
BluetoothCodecConfig[] mCodecConfigs = {mCodecConfigAAC, mCodecConfigSBC};
- mCodecStatus = new BluetoothCodecStatus(mCodecConfigSBC, null, mCodecConfigs);
+ mCodecStatus = new BluetoothCodecStatus(mCodecConfigSBC, null,
+ Arrays.asList(mCodecConfigs));
when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus);
mController.onBluetoothServiceConnected(mBluetoothA2dp);
List<Integer> indexList = new ArrayList<>();
diff --git a/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceControllerTest.java
index 0f01e00..3a34aa0 100644
--- a/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceControllerTest.java
@@ -45,6 +45,9 @@
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
+import java.util.Arrays;
+import java.util.List;
+
@RunWith(RobolectricTestRunner.class)
public class BluetoothCodecDialogPreferenceControllerTest {
@@ -85,29 +88,41 @@
mPreference = new BluetoothCodecDialogPreference(mContext);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
mController.displayPreference(mScreen);
- mCodecConfigSBC = new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
- BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST,
- BluetoothCodecConfig.SAMPLE_RATE_96000 | BluetoothCodecConfig.SAMPLE_RATE_176400,
- BluetoothCodecConfig.BITS_PER_SAMPLE_32,
- BluetoothCodecConfig.CHANNEL_MODE_MONO | BluetoothCodecConfig.CHANNEL_MODE_STEREO,
- 0, 0, 0, 0);
- mCodecConfigAAC = new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC,
- BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST,
- BluetoothCodecConfig.SAMPLE_RATE_48000 | BluetoothCodecConfig.SAMPLE_RATE_88200,
- BluetoothCodecConfig.BITS_PER_SAMPLE_16 | BluetoothCodecConfig.BITS_PER_SAMPLE_24,
- BluetoothCodecConfig.CHANNEL_MODE_STEREO,
- 0, 0, 0, 0);
- mCodecConfigAPTX = new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX);
- mCodecConfigAPTXHD = new BluetoothCodecConfig(
- BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD);
- mCodecConfigLDAC = new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC);
+ mCodecConfigSBC = new BluetoothCodecConfig.Builder()
+ .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC)
+ .setCodecPriority(BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST)
+ .setSampleRate(BluetoothCodecConfig.SAMPLE_RATE_96000
+ | BluetoothCodecConfig.SAMPLE_RATE_176400)
+ .setBitsPerSample(BluetoothCodecConfig.BITS_PER_SAMPLE_32)
+ .setChannelMode(BluetoothCodecConfig.CHANNEL_MODE_MONO
+ | BluetoothCodecConfig.CHANNEL_MODE_STEREO)
+ .build();
+ mCodecConfigAAC = new BluetoothCodecConfig.Builder()
+ .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC)
+ .setCodecPriority(BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST)
+ .setSampleRate(BluetoothCodecConfig.SAMPLE_RATE_48000
+ | BluetoothCodecConfig.SAMPLE_RATE_88200)
+ .setBitsPerSample(BluetoothCodecConfig.BITS_PER_SAMPLE_16
+ | BluetoothCodecConfig.BITS_PER_SAMPLE_24)
+ .setChannelMode(BluetoothCodecConfig.CHANNEL_MODE_STEREO)
+ .build();
+ mCodecConfigAPTX = new BluetoothCodecConfig.Builder()
+ .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX)
+ .build();
+ mCodecConfigAPTXHD = new BluetoothCodecConfig.Builder()
+ .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD)
+ .build();
+ mCodecConfigLDAC = new BluetoothCodecConfig.Builder()
+ .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC)
+ .build();
when(mBluetoothA2dp.getActiveDevice()).thenReturn(mActiveDevice);
}
@Test
public void writeConfigurationValues_selectDefault_setHighest() {
BluetoothCodecConfig[] mCodecConfigs = {mCodecConfigAAC, mCodecConfigSBC};
- mCodecStatus = new BluetoothCodecStatus(mCodecConfigSBC, null, mCodecConfigs);
+ mCodecStatus = new BluetoothCodecStatus(mCodecConfigSBC, null,
+ Arrays.asList(mCodecConfigs));
when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus);
when(mBluetoothA2dp.isOptionalCodecsEnabled(mActiveDevice)).thenReturn(
BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED);
@@ -121,7 +136,8 @@
public void writeConfigurationValues_checkCodec() {
BluetoothCodecConfig[] mCodecConfigs = {mCodecConfigAAC, mCodecConfigSBC, mCodecConfigAPTX,
mCodecConfigAPTXHD, mCodecConfigLDAC, mCodecConfigAAC, mCodecConfigSBC};
- mCodecStatus = new BluetoothCodecStatus(mCodecConfigSBC, null, mCodecConfigs);
+ mCodecStatus = new BluetoothCodecStatus(mCodecConfigSBC, null,
+ Arrays.asList(mCodecConfigs));
when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus);
mController.onBluetoothServiceConnected(mBluetoothA2dp);
@@ -148,7 +164,8 @@
public void writeConfigurationValues_resetHighestConfig() {
BluetoothCodecConfig[] mCodecConfigs = {mCodecConfigAAC, mCodecConfigSBC, mCodecConfigAPTX,
mCodecConfigAPTXHD, mCodecConfigLDAC, mCodecConfigAAC, mCodecConfigSBC};
- mCodecStatus = new BluetoothCodecStatus(mCodecConfigAAC, null, mCodecConfigs);
+ mCodecStatus = new BluetoothCodecStatus(mCodecConfigAAC, null,
+ Arrays.asList(mCodecConfigs));
when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus);
mController.onBluetoothServiceConnected(mBluetoothA2dp);
mController.writeConfigurationValues(2);
@@ -178,7 +195,7 @@
@Test
public void onHDAudioEnabled_optionalCodecEnabled_setsCodecTypeAsAAC() {
- BluetoothCodecConfig[] mCodecConfigs = {mCodecConfigAAC, mCodecConfigSBC};
+ List<BluetoothCodecConfig> mCodecConfigs = Arrays.asList(mCodecConfigAAC, mCodecConfigSBC);
mCodecStatus = new BluetoothCodecStatus(mCodecConfigAAC,
/* codecsLocalCapabilities= */ null,
mCodecConfigs);
@@ -194,7 +211,7 @@
}
@Test
public void onHDAudioEnabled_optionalCodecDisabled_setsCodecTypeAsSBC() {
- BluetoothCodecConfig[] mCodecConfigs = {mCodecConfigAAC, mCodecConfigSBC};
+ List<BluetoothCodecConfig> mCodecConfigs = Arrays.asList(mCodecConfigAAC, mCodecConfigSBC);
mCodecStatus = new BluetoothCodecStatus(mCodecConfigAAC,
/* codecsLocalCapabilities= */ null,
mCodecConfigs);
diff --git a/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothQualityDialogPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothQualityDialogPreferenceControllerTest.java
index ef209a2..e50b716 100644
--- a/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothQualityDialogPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothQualityDialogPreferenceControllerTest.java
@@ -43,6 +43,8 @@
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
+import java.util.Arrays;
+
@RunWith(RobolectricTestRunner.class)
public class BluetoothQualityDialogPreferenceControllerTest {
@@ -77,18 +79,16 @@
mPreference = new BluetoothQualityDialogPreference(mContext);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
mController.displayPreference(mScreen);
- mCodecConfigAAC = new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC,
- BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
- BluetoothCodecConfig.SAMPLE_RATE_48000 | BluetoothCodecConfig.SAMPLE_RATE_88200,
- BluetoothCodecConfig.BITS_PER_SAMPLE_NONE,
- BluetoothCodecConfig.CHANNEL_MODE_NONE,
- 0, 0, 0, 0);
- mCodecConfigLDAC = new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
- BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
- BluetoothCodecConfig.SAMPLE_RATE_96000,
- BluetoothCodecConfig.BITS_PER_SAMPLE_NONE,
- BluetoothCodecConfig.CHANNEL_MODE_NONE,
- 1001, 0, 0, 0);
+ mCodecConfigAAC = new BluetoothCodecConfig.Builder()
+ .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC)
+ .setSampleRate(BluetoothCodecConfig.SAMPLE_RATE_48000
+ | BluetoothCodecConfig.SAMPLE_RATE_88200)
+ .build();
+ mCodecConfigLDAC = new BluetoothCodecConfig.Builder()
+ .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC)
+ .setSampleRate(BluetoothCodecConfig.SAMPLE_RATE_96000)
+ .setCodecSpecific1(1001)
+ .build();
when(mBluetoothA2dp.getActiveDevice()).thenReturn(mActiveDevice);
}
@@ -116,7 +116,8 @@
@Test
public void updateState_codeTypeIsLDAC_enablePreference() {
BluetoothCodecConfig[] mCodecConfigs = {mCodecConfigAAC, mCodecConfigLDAC};
- mCodecStatus = new BluetoothCodecStatus(mCodecConfigLDAC, null, mCodecConfigs);
+ mCodecStatus = new BluetoothCodecStatus(mCodecConfigLDAC, null,
+ Arrays.asList(mCodecConfigs));
when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus);
mController.onBluetoothServiceConnected(mBluetoothA2dp);
mController.updateState(mPreference);
@@ -127,7 +128,8 @@
@Test
public void updateState_codeTypeAAC_disablePreference() {
BluetoothCodecConfig[] mCodecConfigs = {mCodecConfigAAC, mCodecConfigLDAC};
- mCodecStatus = new BluetoothCodecStatus(mCodecConfigAAC, null, mCodecConfigs);
+ mCodecStatus = new BluetoothCodecStatus(mCodecConfigAAC, null,
+ Arrays.asList(mCodecConfigs));
when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus);
mController.onBluetoothServiceConnected(mBluetoothA2dp);
mController.updateState(mPreference);
diff --git a/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothSampleRateDialogPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothSampleRateDialogPreferenceControllerTest.java
index c649fdf..fca154d 100644
--- a/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothSampleRateDialogPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothSampleRateDialogPreferenceControllerTest.java
@@ -44,6 +44,7 @@
import org.robolectric.RuntimeEnvironment;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
@RunWith(RobolectricTestRunner.class)
@@ -81,26 +82,26 @@
mPreference = new BluetoothSampleRateDialogPreference(mContext);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
mController.displayPreference(mScreen);
- mCodecConfigAAC = new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC,
- BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
- BluetoothCodecConfig.SAMPLE_RATE_48000 | BluetoothCodecConfig.SAMPLE_RATE_88200,
- BluetoothCodecConfig.BITS_PER_SAMPLE_NONE,
- BluetoothCodecConfig.CHANNEL_MODE_NONE,
- 0, 0, 0, 0);
- mCodecConfigSBC = new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
- BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
- BluetoothCodecConfig.SAMPLE_RATE_96000,
- BluetoothCodecConfig.BITS_PER_SAMPLE_NONE,
- BluetoothCodecConfig.CHANNEL_MODE_NONE,
- 0, 0, 0, 0);
+ mCodecConfigAAC = new BluetoothCodecConfig.Builder()
+ .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC)
+ .setSampleRate(BluetoothCodecConfig.SAMPLE_RATE_48000
+ | BluetoothCodecConfig.SAMPLE_RATE_88200)
+ .build();
+ mCodecConfigSBC = new BluetoothCodecConfig.Builder()
+ .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC)
+ .setSampleRate(BluetoothCodecConfig.SAMPLE_RATE_96000)
+ .build();
when(mBluetoothA2dp.getActiveDevice()).thenReturn(mActiveDevice);
}
@Test
public void writeConfigurationValues_selectDefault_setHighest() {
- mCodecConfigSBC = new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC);
+ BluetoothCodecConfig mCodecConfigSBC = new BluetoothCodecConfig.Builder()
+ .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC)
+ .build();
BluetoothCodecConfig[] mCodecConfigs = {mCodecConfigAAC, mCodecConfigSBC};
- mCodecStatus = new BluetoothCodecStatus(mCodecConfigAAC, null, mCodecConfigs);
+ mCodecStatus = new BluetoothCodecStatus(mCodecConfigAAC, null,
+ Arrays.asList(mCodecConfigs));
when(mBluetoothA2dp.getCodecStatus(
mActiveDevice)).thenReturn(mCodecStatus);
mController.onBluetoothServiceConnected(mBluetoothA2dp);
@@ -132,7 +133,10 @@
@Test
public void getSelectableIndex_verifyList() {
- BluetoothCodecConfig[] mCodecConfigs = {mCodecConfigAAC, mCodecConfigSBC};
+ List<BluetoothCodecConfig> mCodecConfigs = new ArrayList() {{
+ add(mCodecConfigAAC);
+ add(mCodecConfigSBC);
+ }};
mCodecStatus = new BluetoothCodecStatus(mCodecConfigAAC, null, mCodecConfigs);
when(mBluetoothA2dp.getCodecStatus(
mActiveDevice)).thenReturn(mCodecStatus);
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/TopLevelBatteryPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/TopLevelBatteryPreferenceControllerTest.java
index 700522a..da0002c 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/TopLevelBatteryPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/TopLevelBatteryPreferenceControllerTest.java
@@ -21,11 +21,7 @@
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -37,14 +33,11 @@
import androidx.preference.Preference;
import com.android.settings.R;
-import com.android.settings.testutils.FakeFeatureFactory;
-import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
@@ -53,24 +46,14 @@
@RunWith(RobolectricTestRunner.class)
public class TopLevelBatteryPreferenceControllerTest {
private Context mContext;
- private FakeFeatureFactory mFeatureFactory;
private TopLevelBatteryPreferenceController mController;
private BatterySettingsFeatureProvider mBatterySettingsFeatureProvider;
- private ArgumentCaptor<Intent> mIntentArgumentCaptor;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mFeatureFactory = FakeFeatureFactory.setupForTest();
mContext = spy(Robolectric.setupActivity(Activity.class));
mController = new TopLevelBatteryPreferenceController(mContext, "test_key");
- mBatterySettingsFeatureProvider =
- mFeatureFactory.batterySettingsFeatureProvider;
- }
-
- @After
- public void cleanUp() {
- TopLevelBatteryPreferenceController.sReplacingActivityMap.clear();
}
@Test
@@ -85,56 +68,6 @@
}
@Test
- public void handlePreferenceTreeClick_noFragment_noCustomActivityCalled() {
- Preference preference = new Preference(mContext);
-
- assertThat(mController.handlePreferenceTreeClick(preference)).isFalse();
- }
-
- @Test
- public void handlePreferenceTreeClick_sameActivityReturned_noCustomActivityCalled() {
- String fragmentPath = "my.fragment.ClassName";
- Preference preference = mock(Preference.class);
- when(preference.getFragment()).thenReturn(fragmentPath);
- ComponentName pathName = mController.convertClassPathToComponentName(fragmentPath);
- when(mBatterySettingsFeatureProvider.getReplacingActivity(any())).thenReturn(pathName);
-
- assertThat(mController.handlePreferenceTreeClick(preference)).isFalse();
- }
-
- @Test
- @Ignore
- public void handlePreferenceTreeClick_newActivityReturned_newActivityRedirected() {
- String fragmentPath = "my.fragment.ClassName";
- Preference preference = mock(Preference.class);
- when(preference.getFragment()).thenReturn(fragmentPath);
- String newFragmentPath = "my.fragment.NewClassName";
- ComponentName newPathName = mController.convertClassPathToComponentName(newFragmentPath);
- when(mBatterySettingsFeatureProvider.getReplacingActivity(any())).thenReturn(
- newPathName);
- doNothing().when(mContext).startActivity(mIntentArgumentCaptor.capture());
-
- assertThat(mIntentArgumentCaptor.getValue().getComponent()).isEqualTo(newPathName);
- assertThat(mController.handlePreferenceTreeClick(preference)).isTrue();
- }
-
- @Test
- public void handlePreferenceTreeClick_calledMultipleTimes_fetchedFromCache() {
- String fragmentPath = "my.fragment.ClassName";
- Preference preference = mock(Preference.class);
- when(preference.getFragment()).thenReturn(fragmentPath);
- String newFragmentPath = "my.fragment.NewClassName";
- ComponentName newPathName = mController.convertClassPathToComponentName(newFragmentPath);
- when(mBatterySettingsFeatureProvider.getReplacingActivity(any())).thenReturn(
- newPathName);
- doNothing().when(mContext).startActivity(any());
-
- assertThat(mController.handlePreferenceTreeClick(preference)).isTrue();
- assertThat(mController.handlePreferenceTreeClick(preference)).isTrue();
- verify(mBatterySettingsFeatureProvider, times(1)).getReplacingActivity(any());
- }
-
- @Test
public void convertClassPathToComponentName_nullInput_returnsNull() {
assertThat(mController.convertClassPathToComponentName(null)).isNull();
}
diff --git a/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSettingsForSubTest.java b/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSettingsForSubTest.java
index a3c2535..74bddda 100644
--- a/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSettingsForSubTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSettingsForSubTest.java
@@ -74,12 +74,12 @@
private static final String BUTTON_WFC_MODE = "wifi_calling_mode";
private static final String BUTTON_WFC_ROAMING_MODE = "wifi_calling_roaming_mode";
+ private static final String PREFERENCE_NO_OPTIONS_DESC = "no_options_description";
private static final String TEST_EMERGENCY_ADDRESS_CARRIER_APP =
"com.android.settings/.wifi.calling.TestEmergencyAddressCarrierApp";
private TestFragment mFragment;
private Context mContext;
- private TextView mEmptyView;
private final PersistableBundle mBundle = new PersistableBundle();
private MockWifiCallingQueryImsState mQueryImsState;
@@ -100,6 +100,8 @@
@Mock
private View mView;
@Mock
+ private LinkifyDescriptionPreference mDescriptionView;
+ @Mock
private ListWithEntrySummaryPreference mButtonWfcMode;
@Mock
private ListWithEntrySummaryPreference mButtonWfcRoamingMode;
@@ -126,12 +128,10 @@
doReturn(mock(ListWithEntrySummaryPreference.class)).when(mFragment).findPreference(any());
doReturn(mButtonWfcMode).when(mFragment).findPreference(BUTTON_WFC_MODE);
doReturn(mButtonWfcRoamingMode).when(mFragment).findPreference(BUTTON_WFC_ROAMING_MODE);
+ doReturn(mDescriptionView).when(mFragment).findPreference(PREFERENCE_NO_OPTIONS_DESC);
doNothing().when(mFragment).finish();
doReturn(mView).when(mFragment).getView();
- mEmptyView = new TextView(mContext);
- doReturn(mEmptyView).when(mView).findViewById(android.R.id.empty);
-
mSwitchBar = new SettingsMainSwitchBar(mContext);
doReturn(mSwitchBar).when(mView).findViewById(R.id.switch_bar);
@@ -211,8 +211,7 @@
mFragment.onResume();
// Check that WFC roaming preference is shown.
- verify(mPreferenceScreen, times(1)).addPreference(mButtonWfcRoamingMode);
- verify(mPreferenceScreen, never()).removePreference(mButtonWfcRoamingMode);
+ verify(mButtonWfcRoamingMode, times(1)).setVisible(true);
}
@Test
@@ -225,8 +224,7 @@
mFragment.onResume();
// Check that WFC roaming preference is hidden.
- verify(mPreferenceScreen, never()).addPreference(mButtonWfcRoamingMode);
- verify(mPreferenceScreen, times(1)).removePreference(mButtonWfcRoamingMode);
+ verify(mButtonWfcRoamingMode, times(1)).setVisible(false);
}
@Test
@@ -239,8 +237,7 @@
mFragment.onResume();
// Check that WFC roaming preference is hidden.
- verify(mPreferenceScreen, never()).addPreference(mButtonWfcRoamingMode);
- verify(mPreferenceScreen, times(1)).removePreference(mButtonWfcRoamingMode);
+ verify(mButtonWfcRoamingMode, times(1)).setVisible(false);
}
@Test
@@ -253,8 +250,7 @@
mFragment.onResume();
// Check that WFC roaming preference is hidden.
- verify(mPreferenceScreen, never()).addPreference(mButtonWfcRoamingMode);
- verify(mPreferenceScreen, times(1)).removePreference(mButtonWfcRoamingMode);
+ verify(mButtonWfcRoamingMode, times(1)).setVisible(false);
}
@Test
@@ -332,9 +328,9 @@
Activity.RESULT_OK, null);
// Check the WFC preferences is added.
- verify(mPreferenceScreen).addPreference(mButtonWfcMode);
- verify(mPreferenceScreen).addPreference(mButtonWfcRoamingMode);
- verify(mPreferenceScreen).addPreference(mUpdateAddress);
+ verify(mButtonWfcMode).setVisible(true);
+ verify(mButtonWfcRoamingMode).setVisible(true);
+ verify(mUpdateAddress).setVisible(true);
// Check the WFC enable request.
verify(mImsMmTelManager).setVoWiFiSettingEnabled(true);
}
diff --git a/tests/unit/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogControllerTest.java b/tests/unit/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogControllerTest.java
index 5360dac..9cd6f2d 100644
--- a/tests/unit/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogControllerTest.java
+++ b/tests/unit/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogControllerTest.java
@@ -33,6 +33,7 @@
import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController.SIGNAL_STRENGTH_LABEL_ID;
import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController.SIGNAL_STRENGTH_VALUE_ID;
+import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
@@ -78,12 +79,16 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
@RunWith(AndroidJUnit4.class)
public class SimStatusDialogControllerTest {
@Mock
private SimStatusDialogFragment mDialog;
+ @Mock
private TelephonyManager mTelephonyManager;
@Mock
private SubscriptionInfo mSubscriptionInfo;
@@ -109,6 +114,9 @@
@Mock
private LifecycleOwner mLifecycleOwner;
private Lifecycle mLifecycle;
+ private AtomicBoolean mEuiccEnabled;
+ private AtomicReference<String> mEid;
+ private AtomicInteger mUpdatePhoneNumberCount;
private static final String TEST_EID_FROM_CARD = "11111111111111111111111111111111";
private static final String TEST_EID_FROM_MANAGER = "22222222222222222222222222222222";
@@ -139,7 +147,26 @@
doReturn(2).when(mTelephonyManager).getCardIdForDefaultEuicc();
doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mTelephonyManager).getDataNetworkType();
- mController = spy(new SimStatusDialogController(mDialog, mLifecycle, 0 /* phone id */));
+ mUpdatePhoneNumberCount = new AtomicInteger();
+ mEuiccEnabled = new AtomicBoolean(false);
+ mEid = new AtomicReference<String>("");
+ mController = new SimStatusDialogController(mDialog, mLifecycle, 0 /* phone id */) {
+ @Override
+ public TelephonyManager getTelephonyManager() {
+ return mTelephonyManager;
+ }
+
+ @Override
+ public AtomicReference<String> getEid(int slotIndex) {
+ return mEuiccEnabled.get() ? mEid : null;
+ }
+
+ @Override
+ public void updatePhoneNumber() {
+ super.updatePhoneNumber();
+ mUpdatePhoneNumberCount.incrementAndGet();
+ }
+ };
// CellSignalStrength setup
doReturn(0).when(mCellSignalStrengthCdma).getDbm();
doReturn(0).when(mCellSignalStrengthCdma).getAsuLevel();
@@ -157,7 +184,7 @@
.getLogicalToPhysicalSlotMapping();
when(mEuiccManager.isEnabled()).thenReturn(false);
- when(mEuiccManager.getEid()).thenReturn("");
+ mEuiccEnabled.set(false);
when(mEuiccManager.createForCardId(anyInt())).thenReturn(mEuiccManager);
mPersistableBundle = new PersistableBundle();
@@ -183,7 +210,7 @@
public void initialize_shouldUpdatePhoneNumber() {
mController.initialize();
- verify(mController).updatePhoneNumber();
+ assertTrue(mUpdatePhoneNumberCount.get() > 0);
}
@Test
@@ -426,10 +453,9 @@
when(mTelephonyManager.getLogicalToPhysicalSlotMapping()).thenReturn(slotMapping);
when(mEuiccManager.isEnabled()).thenReturn(true);
- when(mEuiccManager.getEid()).thenReturn(null);
+ mEuiccEnabled.set(true);
+ mEid.set(null);
- doNothing().when(mController).requestForUpdateEid();
- mController.updateEid(mController.getEid(0));
mController.initialize();
// Keep 'Not available' if neither the card nor the associated manager can provide EID.
@@ -480,11 +506,10 @@
when(mTelephonyManager.getLogicalToPhysicalSlotMapping()).thenReturn(slotMapping);
when(mEuiccManager.isEnabled()).thenReturn(true);
- when(mEuiccManager.getEid()).thenReturn(TEST_EID_FROM_MANAGER);
+ mEuiccEnabled.set(true);
+ mEid.set(TEST_EID_FROM_CARD);
when(mEuiccManager.createForCardId(0)).thenReturn(mEuiccManager);
- doNothing().when(mController).requestForUpdateEid();
- mController.updateEid(mController.getEid(0));
mController.initialize();
// Set EID retrieved from the card.
@@ -538,13 +563,12 @@
when(mTelephonyManager.getLogicalToPhysicalSlotMapping()).thenReturn(slotMapping);
when(mEuiccManager.isEnabled()).thenReturn(true);
- when(mEuiccManager.getEid()).thenReturn(TEST_EID_FROM_MANAGER);
+ mEuiccEnabled.set(true);
+ mEid.set(TEST_EID_FROM_MANAGER);
when(mEuiccManager.createForCardId(0)).thenThrow(
new RuntimeException("Unexpected card ID was specified"));
when(mEuiccManager.createForCardId(1)).thenReturn(mEuiccManager);
- doNothing().when(mController).requestForUpdateEid();
- mController.updateEid(mController.getEid(0));
mController.initialize();
// Set EID retrieved from the manager associated with the card which cannot provide EID.
@@ -552,6 +576,7 @@
verify(mDialog, never()).removeSettingFromScreen(eq(EID_INFO_VALUE_ID));
}
+ @Ignore
@Test
public void initialize_updateEid_shouldRemoveEid() {
when(mTelephonyManager.getActiveModemCount()).thenReturn(MAX_PHONE_COUNT_DUAL_SIM);
@@ -597,9 +622,9 @@
when(mTelephonyManager.getLogicalToPhysicalSlotMapping()).thenReturn(slotMapping);
when(mEuiccManager.isEnabled()).thenReturn(true);
- when(mEuiccManager.getEid()).thenReturn(TEST_EID_FROM_MANAGER);
+ mEuiccEnabled.set(true);
+ mEid.set(TEST_EID_FROM_MANAGER);
- doNothing().when(mController).requestForUpdateEid();
mController.updateEid(mController.getEid(0));
mController.initialize();
@@ -637,10 +662,9 @@
when(mTelephonyManager.getLogicalToPhysicalSlotMapping()).thenReturn(slotMapping);
when(mEuiccManager.isEnabled()).thenReturn(true);
- when(mEuiccManager.getEid()).thenReturn(null);
+ mEuiccEnabled.set(true);
+ mEid.set(null);
- doNothing().when(mController).requestForUpdateEid();
- mController.updateEid(mController.getEid(0));
mController.initialize();
// Keep 'Not available' if the default eUICC manager cannot provide EID in Single SIM mode.
@@ -677,12 +701,11 @@
when(mTelephonyManager.getLogicalToPhysicalSlotMapping()).thenReturn(slotMapping);
when(mEuiccManager.isEnabled()).thenReturn(true);
- when(mEuiccManager.getEid()).thenReturn(TEST_EID_FROM_MANAGER);
+ mEuiccEnabled.set(true);
+ mEid.set(TEST_EID_FROM_MANAGER);
when(mEuiccManager.createForCardId(anyInt())).thenThrow(
new RuntimeException("EID shall be retrieved from the default eUICC manager"));
- doNothing().when(mController).requestForUpdateEid();
- mController.updateEid(mController.getEid(0));
mController.initialize();
// Set EID retrieved from the default eUICC manager in Single SIM mode.
@@ -719,12 +742,11 @@
when(mTelephonyManager.getLogicalToPhysicalSlotMapping()).thenReturn(slotMapping);
when(mEuiccManager.isEnabled()).thenReturn(true);
- when(mEuiccManager.getEid()).thenReturn(TEST_EID_FROM_MANAGER);
+ mEuiccEnabled.set(true);
+ mEid.set(TEST_EID_FROM_MANAGER);
when(mEuiccManager.createForCardId(anyInt())).thenThrow(
new RuntimeException("EID shall be retrieved from the default eUICC manager"));
- doNothing().when(mController).requestForUpdateEid();
- mController.updateEid(mController.getEid(0));
mController.initialize();
// Set EID retrieved from the default eUICC manager in Single SIM mode.
@@ -760,14 +782,12 @@
when(mTelephonyManager.getLogicalToPhysicalSlotMapping()).thenReturn(slotMapping);
when(mEuiccManager.isEnabled()).thenReturn(false);
- when(mEuiccManager.getEid()).thenReturn(null);
+ mEuiccEnabled.set(false);
+ mEid.set(null);
- doNothing().when(mController).requestForUpdateEid();
- mController.updateEid(mController.getEid(0));
mController.initialize();
// Remove EID if the default eUICC manager indicates that eSIM is not enabled.
- verify(mDialog, never()).setText(eq(EID_INFO_VALUE_ID), any());
verify(mDialog).removeSettingFromScreen(eq(EID_INFO_LABEL_ID));
verify(mDialog).removeSettingFromScreen(eq(EID_INFO_VALUE_ID));
}
diff --git a/tests/unit/src/com/android/settings/network/SubscriptionUtilTest.java b/tests/unit/src/com/android/settings/network/SubscriptionUtilTest.java
index 3d192cf..b0d6365 100644
--- a/tests/unit/src/com/android/settings/network/SubscriptionUtilTest.java
+++ b/tests/unit/src/com/android/settings/network/SubscriptionUtilTest.java
@@ -34,6 +34,7 @@
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -153,8 +154,8 @@
// Each subscription has a unique last 4 digits of the phone number.
TelephonyManager sub1Telmgr = mock(TelephonyManager.class);
TelephonyManager sub2Telmgr = mock(TelephonyManager.class);
- when(sub1Telmgr.getLine1Number()).thenReturn("1112223333");
- when(sub2Telmgr.getLine1Number()).thenReturn("2223334444");
+ when(mSubMgr.getPhoneNumber(SUBID_1)).thenReturn("1112223333");
+ when(mSubMgr.getPhoneNumber(SUBID_2)).thenReturn("2223334444");
when(mTelMgr.createForSubscriptionId(SUBID_1)).thenReturn(sub1Telmgr);
when(mTelMgr.createForSubscriptionId(SUBID_2)).thenReturn(sub2Telmgr);
@@ -167,6 +168,7 @@
assertEquals(CARRIER_2, idNames.get(SUBID_2));
}
+ @Ignore
@Test
public void getUniqueDisplayNames_identicalCarriers_fourDigitsUsed() {
// Both subscriptoins have the same display name.
@@ -182,8 +184,8 @@
// Each subscription has a unique last 4 digits of the phone number.
TelephonyManager sub1Telmgr = mock(TelephonyManager.class);
TelephonyManager sub2Telmgr = mock(TelephonyManager.class);
- when(sub1Telmgr.getLine1Number()).thenReturn("1112223333");
- when(sub2Telmgr.getLine1Number()).thenReturn("2223334444");
+ when(mSubMgr.getPhoneNumber(SUBID_1)).thenReturn("1112223333");
+ when(mSubMgr.getPhoneNumber(SUBID_2)).thenReturn("2223334444");
when(mTelMgr.createForSubscriptionId(SUBID_1)).thenReturn(sub1Telmgr);
when(mTelMgr.createForSubscriptionId(SUBID_2)).thenReturn(sub2Telmgr);
@@ -196,6 +198,7 @@
assertEquals(CARRIER_1 + " 4444", idNames.get(SUBID_2));
}
+ @Ignore
@Test
public void getUniqueDisplayNames_identicalCarriersAfterTrim_fourDigitsUsed() {
// Both subscriptoins have the same display name.
@@ -211,8 +214,8 @@
// Each subscription has a unique last 4 digits of the phone number.
TelephonyManager sub1Telmgr = mock(TelephonyManager.class);
TelephonyManager sub2Telmgr = mock(TelephonyManager.class);
- when(sub1Telmgr.getLine1Number()).thenReturn("1112223333");
- when(sub2Telmgr.getLine1Number()).thenReturn("2223334444");
+ when(mSubMgr.getPhoneNumber(SUBID_1)).thenReturn("1112223333");
+ when(mSubMgr.getPhoneNumber(SUBID_2)).thenReturn("2223334444");
when(mTelMgr.createForSubscriptionId(SUBID_1)).thenReturn(sub1Telmgr);
when(mTelMgr.createForSubscriptionId(SUBID_2)).thenReturn(sub2Telmgr);
@@ -239,8 +242,8 @@
// The subscriptions' phone numbers cannot be revealed to the user.
TelephonyManager sub1Telmgr = mock(TelephonyManager.class);
TelephonyManager sub2Telmgr = mock(TelephonyManager.class);
- when(sub1Telmgr.getLine1Number()).thenReturn("");
- when(sub2Telmgr.getLine1Number()).thenReturn("");
+ when(mSubMgr.getPhoneNumber(SUBID_1)).thenReturn("");
+ when(mSubMgr.getPhoneNumber(SUBID_2)).thenReturn("");
when(mTelMgr.createForSubscriptionId(SUBID_1)).thenReturn(sub1Telmgr);
when(mTelMgr.createForSubscriptionId(SUBID_2)).thenReturn(sub2Telmgr);
@@ -253,6 +256,7 @@
assertEquals(CARRIER_1 + " 2", idNames.get(SUBID_2));
}
+ @Ignore
@Test
public void getUniqueDisplayNames_phoneNumberIdentical_subscriptoinIdFallback() {
// TODO have three here from the same carrier
@@ -274,9 +278,9 @@
TelephonyManager sub1Telmgr = mock(TelephonyManager.class);
TelephonyManager sub2Telmgr = mock(TelephonyManager.class);
TelephonyManager sub3Telmgr = mock(TelephonyManager.class);
- when(sub1Telmgr.getLine1Number()).thenReturn("1112223333");
- when(sub2Telmgr.getLine1Number()).thenReturn("2223334444");
- when(sub3Telmgr.getLine1Number()).thenReturn("5556664444");
+ when(mSubMgr.getPhoneNumber(SUBID_1)).thenReturn("1112223333");
+ when(mSubMgr.getPhoneNumber(SUBID_2)).thenReturn("2223334444");
+ when(mSubMgr.getPhoneNumber(SUBID_3)).thenReturn("5556664444");
when(mTelMgr.createForSubscriptionId(SUBID_1)).thenReturn(sub1Telmgr);
when(mTelMgr.createForSubscriptionId(SUBID_2)).thenReturn(sub2Telmgr);
when(mTelMgr.createForSubscriptionId(SUBID_3)).thenReturn(sub3Telmgr);
@@ -298,9 +302,9 @@
when(info1.getSubscriptionId()).thenReturn(SUBID_1);
when(info1.getDisplayName()).thenReturn(CARRIER_1);
when(mSubMgr.getAvailableSubscriptionInfoList()).thenReturn(Arrays.asList(info1));
+ when(mSubMgr.getPhoneNumber(SUBID_1)).thenReturn("1112223333");
TelephonyManager sub1Telmgr = mock(TelephonyManager.class);
- when(sub1Telmgr.getLine1Number()).thenReturn("1112223333");
when(mTelMgr.createForSubscriptionId(SUBID_1)).thenReturn(sub1Telmgr);
final CharSequence name =
@@ -310,6 +314,7 @@
assertEquals(CARRIER_1, name);
}
+ @Ignore
@Test
public void getUniqueDisplayName_identicalCarriers_correctNameReturned() {
// Each subscription's default display name is unique.
@@ -324,8 +329,8 @@
// Each subscription has a unique last 4 digits of the phone number.
TelephonyManager sub1Telmgr = mock(TelephonyManager.class);
TelephonyManager sub2Telmgr = mock(TelephonyManager.class);
- when(sub1Telmgr.getLine1Number()).thenReturn("1112223333");
- when(sub2Telmgr.getLine1Number()).thenReturn("2223334444");
+ when(mSubMgr.getPhoneNumber(SUBID_1)).thenReturn("1112223333");
+ when(mSubMgr.getPhoneNumber(SUBID_2)).thenReturn("2223334444");
when(mTelMgr.createForSubscriptionId(SUBID_1)).thenReturn(sub1Telmgr);
when(mTelMgr.createForSubscriptionId(SUBID_2)).thenReturn(sub2Telmgr);
@@ -339,6 +344,7 @@
assertEquals(CARRIER_1 + " 4444", name2);
}
+ @Ignore
@Test
public void getUniqueDisplayName_phoneNumberIdentical_correctNameReturned() {
// Each subscription's default display name is unique.
@@ -353,8 +359,8 @@
// Both subscriptions have a the same 4 digits of the phone number.
TelephonyManager sub1Telmgr = mock(TelephonyManager.class);
TelephonyManager sub2Telmgr = mock(TelephonyManager.class);
- when(sub1Telmgr.getLine1Number()).thenReturn("1112224444");
- when(sub2Telmgr.getLine1Number()).thenReturn("2223334444");
+ when(mSubMgr.getPhoneNumber(SUBID_1)).thenReturn("1112223333");
+ when(mSubMgr.getPhoneNumber(SUBID_2)).thenReturn("2223334444");
when(mTelMgr.createForSubscriptionId(SUBID_1)).thenReturn(sub1Telmgr);
when(mTelMgr.createForSubscriptionId(SUBID_2)).thenReturn(sub2Telmgr);
@@ -377,7 +383,7 @@
when(mSubMgr.getAvailableSubscriptionInfoList()).thenReturn(Arrays.asList(info1));
TelephonyManager sub1Telmgr = mock(TelephonyManager.class);
- when(sub1Telmgr.getLine1Number()).thenReturn("1112223333");
+ when(mSubMgr.getPhoneNumber(SUBID_1)).thenReturn("1112223333");
when(mTelMgr.createForSubscriptionId(SUBID_1)).thenReturn(sub1Telmgr);
// Subscription id is different than the one returned by the subscription manager.
@@ -397,7 +403,7 @@
when(mSubMgr.getAvailableSubscriptionInfoList()).thenReturn(Arrays.asList(info1));
TelephonyManager sub1Telmgr = mock(TelephonyManager.class);
- when(sub1Telmgr.getLine1Number()).thenReturn("1112223333");
+ when(mSubMgr.getPhoneNumber(SUBID_1)).thenReturn("1112223333");
when(mTelMgr.createForSubscriptionId(SUBID_1)).thenReturn(sub1Telmgr);
final CharSequence name =
@@ -416,7 +422,7 @@
Arrays.asList(info1));
TelephonyManager sub1Telmgr = mock(TelephonyManager.class);
- when(sub1Telmgr.getLine1Number()).thenReturn("1112223333");
+ when(mSubMgr.getPhoneNumber(SUBID_1)).thenReturn("1112223333");
when(mTelMgr.createForSubscriptionId(SUBID_1)).thenReturn(sub1Telmgr);
SubscriptionInfo info2 = null;
diff --git a/tests/unit/src/com/android/settings/network/telephony/NetworkSelectSettingsTest.java b/tests/unit/src/com/android/settings/network/telephony/NetworkSelectSettingsTest.java
index 6449c65..7d86018 100644
--- a/tests/unit/src/com/android/settings/network/telephony/NetworkSelectSettingsTest.java
+++ b/tests/unit/src/com/android/settings/network/telephony/NetworkSelectSettingsTest.java
@@ -122,10 +122,6 @@
public TargetClass(NetworkSelectSettingsTest env) {
mTestEnv = env;
-
- Bundle bundle = new Bundle();
- bundle.putInt(Settings.EXTRA_SUB_ID, SUB_ID);
- setArguments(bundle);
}
@Override
@@ -184,6 +180,11 @@
protected boolean enableAggregation(Context context) {
return mTestEnv.mIsAggregationEnabled;
}
+
+ @Override
+ protected int getSubId() {
+ return SUB_ID;
+ }
}
@Test