summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AndroidManifest.xml15
-rw-r--r--res/anim/enrollment_fingerprint_isolated_ridge_1_path_animation.xml53
-rw-r--r--res/anim/enrollment_fingerprint_isolated_ridge_2_path_animation.xml53
-rw-r--r--res/anim/enrollment_fingerprint_isolated_ridge_5_path_animation.xml53
-rw-r--r--res/anim/enrollment_fingerprint_isolated_ridge_6_path_animation.xml43
-rw-r--r--res/anim/enrollment_fingerprint_isolated_ridge_7_path_animation.xml53
-rw-r--r--res/drawable/enrollment_fingerprint_isolated.xml81
-rw-r--r--res/drawable/enrollment_fingerprint_isolated_animation.xml35
-rw-r--r--res/interpolator/enrollment_fingerprint_isolated_animation_interpolator_0.xml19
-rw-r--r--res/interpolator/enrollment_fingerprint_isolated_animation_interpolator_1.xml19
-rw-r--r--res/interpolator/enrollment_fingerprint_isolated_animation_interpolator_2.xml19
-rw-r--r--res/layout/delete_managed_profile_dialog.xml73
-rw-r--r--res/layout/fingerprint_enroll_enrolling_content.xml8
-rw-r--r--res/layout/storage_internal_forget.xml51
-rwxr-xr-xres/values/dimens.xml7
-rw-r--r--res/values/strings.xml20
-rw-r--r--res/values/styles.xml7
-rw-r--r--res/xml/timezones.xml3
-rw-r--r--src/com/android/settings/ChooseLockGeneric.java14
-rw-r--r--src/com/android/settings/ChooseLockPassword.java34
-rw-r--r--src/com/android/settings/ChooseLockPattern.java12
-rw-r--r--src/com/android/settings/ChooseLockSettingsHelper.java3
-rw-r--r--src/com/android/settings/ConfirmLockPassword.java14
-rw-r--r--src/com/android/settings/ConfirmLockPattern.java13
-rw-r--r--src/com/android/settings/CredentialStorage.java3
-rw-r--r--src/com/android/settings/CryptKeeperConfirm.java6
-rw-r--r--src/com/android/settings/CryptKeeperSettings.java3
-rw-r--r--src/com/android/settings/EncryptionInterstitial.java3
-rw-r--r--src/com/android/settings/OwnerInfoSettings.java2
-rw-r--r--src/com/android/settings/ScreenPinningSettings.java14
-rw-r--r--src/com/android/settings/SecuritySettings.java41
-rw-r--r--src/com/android/settings/Settings.java3
-rw-r--r--src/com/android/settings/SettingsActivity.java2
-rw-r--r--src/com/android/settings/TrustAgentSettings.java7
-rw-r--r--src/com/android/settings/Utils.java28
-rw-r--r--src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java3
-rw-r--r--src/com/android/settings/applications/DefaultBrowserPreference.java3
-rw-r--r--src/com/android/settings/applications/DefaultDialerPreference.java15
-rw-r--r--src/com/android/settings/deviceinfo/PrivateVolumeForget.java68
-rw-r--r--src/com/android/settings/deviceinfo/PrivateVolumeFormat.java (renamed from src/com/android/settings/deviceinfo/PrivateVolumeFormatConfirm.java)4
-rw-r--r--src/com/android/settings/deviceinfo/PrivateVolumeSettings.java45
-rw-r--r--src/com/android/settings/deviceinfo/PrivateVolumeUnmount.java (renamed from src/com/android/settings/deviceinfo/PrivateVolumeUnmountConfirm.java)2
-rw-r--r--src/com/android/settings/deviceinfo/PublicVolumeSettings.java21
-rw-r--r--src/com/android/settings/deviceinfo/StorageSettings.java37
-rw-r--r--src/com/android/settings/deviceinfo/StorageWizardFormatConfirm.java19
-rw-r--r--src/com/android/settings/deviceinfo/StorageWizardFormatProgress.java19
-rw-r--r--src/com/android/settings/deviceinfo/StorageWizardInit.java22
-rw-r--r--src/com/android/settings/deviceinfo/StorageWizardMoveProgress.java9
-rw-r--r--src/com/android/settings/fingerprint/FingerprintEnrollEnrolling.java76
-rw-r--r--src/com/android/settings/notification/AppNotificationSettings.java4
-rw-r--r--src/com/android/settings/notification/NotificationSettings.java3
-rw-r--r--src/com/android/settings/users/UserDialogs.java73
-rw-r--r--src/com/android/settings/users/UserSettings.java2
53 files changed, 1028 insertions, 211 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 435236af4..04461789b 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1490,7 +1490,7 @@
</activity>
<activity
- android:name="Settings$StorageVolumeSettingsActivity"
+ android:name="Settings$PublicVolumeSettingsActivity"
android:label="@string/storage_settings_title"
android:taskAffinity="com.android.settings"
android:parentActivityName="Settings$StorageSettingsActivity">
@@ -1508,6 +1508,19 @@
android:resource="@id/storage_settings" />
</activity>
+ <activity
+ android:name="Settings$PrivateVolumeForgetActivity"
+ android:label="@string/storage_settings_title"
+ android:taskAffinity="com.android.settings"
+ android:parentActivityName="Settings$StorageSettingsActivity"
+ android:exported="true"
+ android:permission="android.permission.MOUNT_UNMOUNT_FILESYSTEMS">
+ <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
+ android:value="com.android.settings.deviceinfo.PrivateVolumeForget" />
+ <meta-data android:name="com.android.settings.TOP_LEVEL_HEADER_ID"
+ android:resource="@id/storage_settings" />
+ </activity>
+
<!-- Exported for SystemUI to launch into -->
<activity android:name=".deviceinfo.StorageWizardInit"
android:theme="@style/SuwThemeMaterial.Light"
diff --git a/res/anim/enrollment_fingerprint_isolated_ridge_1_path_animation.xml b/res/anim/enrollment_fingerprint_isolated_ridge_1_path_animation.xml
new file mode 100644
index 000000000..333271537
--- /dev/null
+++ b/res/anim/enrollment_fingerprint_isolated_ridge_1_path_animation.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 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
+ -->
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="233"
+ android:propertyName="trimPathEnd"
+ android:valueFrom="0.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="566"
+ android:propertyName="trimPathEnd"
+ android:valueFrom="0.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="700"
+ android:propertyName="trimPathStart"
+ android:valueFrom="0.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="433"
+ android:propertyName="trimPathStart"
+ android:valueFrom="0.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/enrollment_fingerprint_isolated_animation_interpolator_1" />
+ </set>
+</set>
diff --git a/res/anim/enrollment_fingerprint_isolated_ridge_2_path_animation.xml b/res/anim/enrollment_fingerprint_isolated_ridge_2_path_animation.xml
new file mode 100644
index 000000000..928512206
--- /dev/null
+++ b/res/anim/enrollment_fingerprint_isolated_ridge_2_path_animation.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 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
+ -->
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="733"
+ android:propertyName="trimPathEnd"
+ android:valueFrom="1.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="533"
+ android:propertyName="trimPathEnd"
+ android:valueFrom="1.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/enrollment_fingerprint_isolated_animation_interpolator_2" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="366"
+ android:propertyName="trimPathStart"
+ android:valueFrom="1.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="633"
+ android:propertyName="trimPathStart"
+ android:valueFrom="1.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/enrollment_fingerprint_isolated_animation_interpolator_2" />
+ </set>
+</set>
diff --git a/res/anim/enrollment_fingerprint_isolated_ridge_5_path_animation.xml b/res/anim/enrollment_fingerprint_isolated_ridge_5_path_animation.xml
new file mode 100644
index 000000000..1329b7bf9
--- /dev/null
+++ b/res/anim/enrollment_fingerprint_isolated_ridge_5_path_animation.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 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
+ -->
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="166"
+ android:propertyName="trimPathEnd"
+ android:valueFrom="0.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="900"
+ android:propertyName="trimPathEnd"
+ android:valueFrom="0.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="600"
+ android:propertyName="trimPathStart"
+ android:valueFrom="0.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="833"
+ android:propertyName="trimPathStart"
+ android:valueFrom="0.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/enrollment_fingerprint_isolated_animation_interpolator_1" />
+ </set>
+</set>
diff --git a/res/anim/enrollment_fingerprint_isolated_ridge_6_path_animation.xml b/res/anim/enrollment_fingerprint_isolated_ridge_6_path_animation.xml
new file mode 100644
index 000000000..eeb96818a
--- /dev/null
+++ b/res/anim/enrollment_fingerprint_isolated_ridge_6_path_animation.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 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
+ -->
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="400"
+ android:propertyName="trimPathEnd"
+ android:valueFrom="1.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="900"
+ android:propertyName="trimPathEnd"
+ android:valueFrom="1.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/enrollment_fingerprint_isolated_animation_interpolator_0" />
+ </set>
+ <objectAnimator
+ android:duration="866"
+ android:propertyName="trimPathStart"
+ android:valueFrom="1.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/enrollment_fingerprint_isolated_animation_interpolator_2" />
+</set>
diff --git a/res/anim/enrollment_fingerprint_isolated_ridge_7_path_animation.xml b/res/anim/enrollment_fingerprint_isolated_ridge_7_path_animation.xml
new file mode 100644
index 000000000..69acef6c4
--- /dev/null
+++ b/res/anim/enrollment_fingerprint_isolated_ridge_7_path_animation.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 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
+ -->
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="trimPathEnd"
+ android:valueFrom="0.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="966"
+ android:propertyName="trimPathEnd"
+ android:valueFrom="0.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="533"
+ android:propertyName="trimPathStart"
+ android:valueFrom="0.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="900"
+ android:propertyName="trimPathStart"
+ android:valueFrom="0.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/enrollment_fingerprint_isolated_animation_interpolator_1" />
+ </set>
+</set>
diff --git a/res/drawable/enrollment_fingerprint_isolated.xml b/res/drawable/enrollment_fingerprint_isolated.xml
new file mode 100644
index 000000000..2f1db7a60
--- /dev/null
+++ b/res/drawable/enrollment_fingerprint_isolated.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 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
+ -->
+<vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:name="enrollment_fingerprint_isolated"
+ android:width="75dp"
+ android:viewportWidth="75"
+ android:height="88dp"
+ android:viewportHeight="88" >
+ <group
+ android:name="fingerprint_ridges_2"
+ android:translateX="37.5835"
+ android:translateY="43.66685" >
+ <group
+ android:name="ridge_5" >
+ <path
+ android:name="ridge_5_path"
+ android:pathData="M 24.9488677979,32.3508300781 c -1.81059265137,0.338500976562 -3.58520507812,0.447387695312 -4.62879943848,0.447387695312 c -4.12730407715,0.0 -8.05894470215,-0.96842956543 -11.5207061768,-3.45275878906 c -5.33699035645,-3.830078125 -8.56369018555,-10.0885009766 -8.56369018555,-17.1589355469"
+ android:strokeColor="#10000000"
+ android:strokeWidth="5"
+ android:strokeLineCap="round"
+ android:trimPathEnd="0" />
+ </group>
+ <group
+ android:name="ridge_4" >
+ <path
+ android:name="ridge_7_path"
+ android:pathData="M -9.23379516602,40.8356933594 c -3.24549865723,-3.46032714844 -5.1540222168,-5.77195739746 -7.87710571289,-10.9068603516 c -2.76379394531,-5.21166992188 -4.04838562012,-11.3482666016 -4.04838562012,-17.6915283203 c 0.0,-11.6563720703 9.44940185547,-21.1059570312 21.1058959961,-21.1059570312 c 11.6564941406,0.0 21.1058959961,9.44958496094 21.1058959961,21.1059570312"
+ android:strokeColor="#10000000"
+ android:strokeWidth="5"
+ android:strokeLineCap="round"
+ android:trimPathEnd="0" />
+ </group>
+ <group
+ android:name="ridge_3" >
+ <path
+ android:name="ridge_6_path"
+ android:pathData="M -28.8249053955,28.5169677734 c -2.41259765625,-6.82202148438 -2.85319519043,-12.3121337891 -2.85319519043,-16.3226318359 c 0.0,-4.64868164062 0.792999267578,-9.06323242188 2.59269714355,-13.0396728516 c 4.96929931641,-10.9801025391 16.0211029053,-18.619140625 28.857208252,-18.619140625 c 17.4846954346,0.0 31.6587982178,14.1740722656 31.6587982178,31.6588134766 c 0.0,5.82824707031 -4.72470092773,10.5529785156 -10.5529022217,10.5529785156 c -5.82820129395,0.0 -10.5529937744,-4.72473144531 -10.5529937744,-10.5529785156 c 0.0,-5.82824707031 -4.72470092773,-10.5529785156 -10.5529022217,-10.5529785156 c -5.82820129395,0.0 -10.5529022217,4.72473144531 -10.5529022217,10.5529785156 c 0.0,8.17932128906 3.10879516602,15.5925292969 8.25030517578,21.0004882812 c 3.88919067383,4.09069824219 7.77758789062,6.64123535156 14.2838897705,8.52136230469"
+ android:strokeColor="#10000000"
+ android:strokeWidth="5"
+ android:strokeLineCap="round"
+ android:trimPathStart="1" />
+ </group>
+ <group
+ android:name="ridge_2" >
+ <path
+ android:name="ridge_2_path"
+ android:pathData="M -34.4861907959,-11.6943359375 c 3.78790283203,-5.64636230469 8.36389160156,-9.94665527344 14.3594970703,-13.2164306641 c 5.99560546875,-3.26977539062 12.8716125488,-5.1279296875 20.1817016602,-5.1279296875 c 7.27980041504,0.0 14.129196167,1.84289550781 20.1071014404,5.08740234375 c 5.97790527344,3.24450683594 10.7957000732,7.759765625 14.5897064209,13.3666992188"
+ android:strokeColor="#10000000"
+ android:strokeWidth="5"
+ android:strokeLineCap="round"
+ android:trimPathStart="1" />
+ </group>
+ <group
+ android:name="ridge_1"
+ android:translateX="-97.5"
+ android:translateY="-142.5" >
+ <path
+ android:name="ridge_1_path"
+ android:pathData="M 121.472564697,107.859741211 c -7.39790344238,-4.03979492188 -15.2462921143,-6.34167480469 -24.3116912842,-6.34167480469 c -9.06539916992,0.0 -16.2951049805,2.40405273438 -23.12550354,6.34167480469"
+ android:strokeColor="#10000000"
+ android:strokeWidth="5"
+ android:strokeLineCap="round"
+ android:trimPathEnd="0" />
+ </group>
+ </group>
+</vector>
diff --git a/res/drawable/enrollment_fingerprint_isolated_animation.xml b/res/drawable/enrollment_fingerprint_isolated_animation.xml
new file mode 100644
index 000000000..39c27f053
--- /dev/null
+++ b/res/drawable/enrollment_fingerprint_isolated_animation.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 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
+ -->
+<animated-vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/enrollment_fingerprint_isolated" >
+ <target
+ android:name="ridge_5_path"
+ android:animation="@anim/enrollment_fingerprint_isolated_ridge_5_path_animation" />
+ <target
+ android:name="ridge_7_path"
+ android:animation="@anim/enrollment_fingerprint_isolated_ridge_7_path_animation" />
+ <target
+ android:name="ridge_6_path"
+ android:animation="@anim/enrollment_fingerprint_isolated_ridge_6_path_animation" />
+ <target
+ android:name="ridge_2_path"
+ android:animation="@anim/enrollment_fingerprint_isolated_ridge_2_path_animation" />
+ <target
+ android:name="ridge_1_path"
+ android:animation="@anim/enrollment_fingerprint_isolated_ridge_1_path_animation" />
+</animated-vector>
diff --git a/res/interpolator/enrollment_fingerprint_isolated_animation_interpolator_0.xml b/res/interpolator/enrollment_fingerprint_isolated_animation_interpolator_0.xml
new file mode 100644
index 000000000..7f442ee5a
--- /dev/null
+++ b/res/interpolator/enrollment_fingerprint_isolated_animation_interpolator_0.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 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
+ -->
+<pathInterpolator
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0.0,0.0 c 0.4,0.0 0.5,1.0 1.0,1.0" />
diff --git a/res/interpolator/enrollment_fingerprint_isolated_animation_interpolator_1.xml b/res/interpolator/enrollment_fingerprint_isolated_animation_interpolator_1.xml
new file mode 100644
index 000000000..e10db01ac
--- /dev/null
+++ b/res/interpolator/enrollment_fingerprint_isolated_animation_interpolator_1.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 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
+ -->
+<pathInterpolator
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0.0,0.0 c 0.8,0.0 0.5,1.0 1.0,1.0" />
diff --git a/res/interpolator/enrollment_fingerprint_isolated_animation_interpolator_2.xml b/res/interpolator/enrollment_fingerprint_isolated_animation_interpolator_2.xml
new file mode 100644
index 000000000..736eac68f
--- /dev/null
+++ b/res/interpolator/enrollment_fingerprint_isolated_animation_interpolator_2.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 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
+ -->
+<pathInterpolator
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0.0,0.0 c 0.4,0.0 0.6,1.0 1.0,1.0" />
diff --git a/res/layout/delete_managed_profile_dialog.xml b/res/layout/delete_managed_profile_dialog.xml
new file mode 100644
index 000000000..da763c9c1
--- /dev/null
+++ b/res/layout/delete_managed_profile_dialog.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (C) 2015 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.
+ */
+-->
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingTop="@dimen/delete_profile_dialog_padding_top"
+ android:paddingLeft="@dimen/delete_profile_dialog_padding_left_right"
+ android:paddingRight="@dimen/delete_profile_dialog_padding_left_right"
+ android:fadeScrollbars="false" >
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical" >
+
+ <TextView
+ android:id="@+id/delete_managed_profile_opening_paragraph"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/opening_paragraph_delete_profile_unknown_company"
+ style="@style/TextAppearance.RemoveDialogContent" />
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="@dimen/mdm_app_info_height"
+ android:layout_alignParentLeft="true"
+ android:layout_centerInParent="true"
+ android:layout_gravity="center_vertical"
+ android:orientation="horizontal"
+ android:paddingBottom="@dimen/mdm_app_info_padding_top_bottom"
+ android:paddingTop="@dimen/mdm_app_info_padding_top_bottom" >
+
+ <ImageView
+ android:id="@+id/delete_managed_profile_mdm_icon_view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:scaleType="centerInside"
+ android:gravity="center_vertical" />
+
+ <TextView
+ android:id="@+id/delete_managed_profile_device_manager_name"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:gravity="center_vertical"
+ android:paddingLeft="@dimen/mdm_app_name_padding_left"
+ style="@style/TextAppearance.RemoveDialogContent" />
+ </LinearLayout>
+
+ <TextView
+ android:id="@+id/delete_managed_profile_closing_paragraph"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/work_profile_confirm_remove_message"
+ style="@style/TextAppearance.RemoveDialogContent" />
+ </LinearLayout>
+
+</ScrollView> \ No newline at end of file
diff --git a/res/layout/fingerprint_enroll_enrolling_content.xml b/res/layout/fingerprint_enroll_enrolling_content.xml
index 6da744e53..9fa503b40 100644
--- a/res/layout/fingerprint_enroll_enrolling_content.xml
+++ b/res/layout/fingerprint_enroll_enrolling_content.xml
@@ -23,12 +23,18 @@
android:layout_gravity="center_horizontal">
<ImageView
- android:id="@+id/fingerprint_animator"
android:layout_width="88dp"
android:layout_height="88dp"
android:layout_centerInParent="true"
android:src="@drawable/fingerprint_indicator" />
+ <ImageView
+ android:id="@+id/fingerprint_animator"
+ android:layout_width="88dp"
+ android:layout_height="88dp"
+ android:layout_centerInParent="true"
+ android:src="@drawable/enrollment_fingerprint_isolated_animation" />
+
<ProgressBar
android:id="@+id/fingerprint_progress_bar"
android:layout_width="192dp"
diff --git a/res/layout/storage_internal_forget.xml b/res/layout/storage_internal_forget.xml
new file mode 100644
index 000000000..cb47d3ba8
--- /dev/null
+++ b/res/layout/storage_internal_forget.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 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="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <ScrollView
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1">
+ <TextView
+ android:id="@+id/body"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="@dimen/suw_description_margin_top"
+ android:paddingBottom="@dimen/suw_description_margin_bottom"
+ android:paddingStart="@dimen/suw_layout_margin_sides"
+ android:paddingEnd="@dimen/suw_layout_margin_sides"
+ android:lineSpacingExtra="@dimen/suw_description_line_spacing_extra"
+ android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textColor="?android:attr/textColorPrimary" />
+ </ScrollView>
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:padding="4dp">
+ <Button
+ android:id="@+id/confirm"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/storage_menu_forget" />
+ </FrameLayout>
+
+</LinearLayout>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 30be6e867..e4e925588 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -232,4 +232,11 @@
<dimen name="fab_margin">16dp</dimen>
<dimen name="fab_elevation">12dp</dimen>
<dimen name="fab_press_translation_z">9dp</dimen>
+
+ <!-- Delete managed profile dialog -->
+ <dimen name="delete_profile_dialog_padding_top">16dp</dimen>
+ <dimen name="delete_profile_dialog_padding_left_right">24dp</dimen>
+ <dimen name="mdm_app_info_height">72dp</dimen>
+ <dimen name="mdm_app_info_padding_top_bottom">8dp</dimen>
+ <dimen name="mdm_app_name_padding_left">16dp</dimen>
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index c1f7dc331..682786719 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -2287,6 +2287,8 @@
<string name="storage_menu_format_internal">Erase &amp; format as internal storage</string>
<!-- Storage setting. Menu option for USB transfer settings [CHAR LIMIT=30]-->
<string name="storage_menu_usb">USB computer connection</string>
+ <!-- Storage setting. Menu option for forgetting a storage device [CHAR LIMIT=30]-->
+ <string name="storage_menu_forget">Forget</string>
<!-- Storage setting. Title for USB transfer settings [CHAR LIMIT=30]-->
<string name="storage_title_usb">USB computer connection</string>
@@ -2346,6 +2348,12 @@
<string name="storage_internal_unmount_details"><b>When you eject this <xliff:g id="name" example="SD card">^1</xliff:g>, apps stored on it will stop working, and media files stored on it will not be available until it is reinserted.</b>
\n\nThis <xliff:g id="name" example="SD card">^1</xliff:g> is formatted to work on this device only. It won\'t work on any others.</string>
+ <!-- Body of dialog informing user about consequences of forgetting an internal storage device [CHAR LIMIT=NONE]-->
+ <string name="storage_internal_forget_details">To use the apps, photos, or data this <xliff:g id="name" example="SD card">^1</xliff:g> contains, reinsert it.
+\n\nAlternatively, you can choose to forget this storage if the device isn\'t available.
+\n\nIf you choose to forget, all the data the device contains will be lost forever.
+\n\nYou can reinstall the apps later, but their data stored on this device will be lost.</string>
+
<!-- Title of wizard step prompting user to setup a storage device [CHAR LIMIT=32] -->
<string name="storage_wizard_init_title">Set up your <xliff:g id="name" example="SD card">^1</xliff:g></string>
<!-- Title of wizard choice to use storage device as external storage [CHAR LIMIT=64] -->
@@ -2364,6 +2372,14 @@
\n\nAfter formatting, this <xliff:g id="name" example="SD card">^1</xliff:g> will only work in this device.
\n\n<b>Formatting erases all data currently stored on the <xliff:g id="name" example="SD card">^1</xliff:g>.</b> To avoid losing the data, consider backing it up.
</string>
+
+ <!-- Title of wizard step prompting user to format a storage device [CHAR LIMIT=32] -->
+ <string name="storage_wizard_format_confirm_public_title">Format as portable storage</string>
+ <!-- Body of wizard step prompting user to format a storage device [CHAR LIMIT=NONE] -->
+ <string name="storage_wizard_format_confirm_public_body">This requires the <xliff:g id="name" example="SD card">^1</xliff:g> to be formatted.
+\n\n<b>Formatting erases all data currently stored on the <xliff:g id="name" example="SD card">^1</xliff:g>.</b> To avoid losing the data, consider backing it up.
+ </string>
+
<!-- Next button text of wizard step prompting user to format a storage device [CHAR LIMIT=32] -->
<string name="storage_wizard_format_confirm_next">Erase &amp; format</string>
@@ -5443,7 +5459,7 @@
<!-- User removal confirmation message [CHAR LIMIT=none] -->
<string name="user_confirm_remove_message">All apps and data will be deleted.</string>
<!-- Work profile removal confirmation message [CHAR LIMIT=none] -->
- <string name="work_profile_confirm_remove_message">All apps and data in this profile will be deleted.</string>
+ <string name="work_profile_confirm_remove_message">All apps and data in this profile will be deleted if you continue.</string>
<!-- User profile removal confirmation message [CHAR LIMIT=none] -->
<string name="user_profile_confirm_remove_message">All apps and data will be deleted.</string>
<!-- Setting label to show that a new user is being added [CHAR LIMIT=30] -->
@@ -6286,6 +6302,8 @@
<!-- Title for a work profile. [CHAR LIMIT=25] -->
<string name="managed_user_title">Work profile</string>
+ <!-- Opening string on the dialog that prompts the user to confirm that they really want to delete their existing work profile. The administration app icon and name appear after the final colon. [CHAR LIMIT=NONE] -->
+ <string name="opening_paragraph_delete_profile_unknown_company">This profile is managed by:</string>
<!-- Summary Title for saying that the preference is experimental and will evolve over time due to User feedback. [CHAR LIMIT=NONE] -->
<string name="experimental_preference">(Experimental)</string>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 7a917a962..d0d2ead32 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -327,4 +327,9 @@
<item name="android:textColor">?android:attr/textColorPrimary</item>
<item name="android:textStyle">normal</item>
</style>
-</resources>
+
+ <style name="TextAppearance.RemoveDialogContent" parent="@android:style/TextAppearance.Material">
+ <item name="android:textSize">16sp</item>
+ <item name="android:textColor">?android:attr/textColorPrimary</item>
+ </style>
+</resources> \ No newline at end of file
diff --git a/res/xml/timezones.xml b/res/xml/timezones.xml
index b6f1f1d88..4426495b0 100644
--- a/res/xml/timezones.xml
+++ b/res/xml/timezones.xml
@@ -1,5 +1,4 @@
<timezones>
- <timezone id="Pacific/Majuro"></timezone>
<timezone id="Pacific/Midway"></timezone>
<timezone id="Pacific/Honolulu"></timezone>
<timezone id="America/Anchorage"></timezone>
@@ -84,6 +83,8 @@
<timezone id="Asia/Vladivostok"></timezone>
<timezone id="Pacific/Guam"></timezone>
<timezone id="Asia/Magadan"></timezone>
+ <timezone id="Pacific/Noumea"></timezone>
+ <timezone id="Pacific/Majuro"></timezone>
<timezone id="Pacific/Auckland"></timezone>
<timezone id="Pacific/Fiji"></timezone>
<timezone id="Pacific/Tongatapu"></timezone>
diff --git a/src/com/android/settings/ChooseLockGeneric.java b/src/com/android/settings/ChooseLockGeneric.java
index a3bd5a108..4b2de72a9 100644
--- a/src/com/android/settings/ChooseLockGeneric.java
+++ b/src/com/android/settings/ChooseLockGeneric.java
@@ -29,6 +29,7 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Process;
+import android.os.UserHandle;
import android.preference.Preference;
import android.preference.PreferenceScreen;
import android.security.KeyStore;
@@ -168,7 +169,7 @@ public class ChooseLockGeneric extends SettingsActivity {
Preference preference) {
final String key = preference.getKey();
- if (!isUnlockMethodSecure(key) && mLockPatternUtils.isSecure()) {
+ if (!isUnlockMethodSecure(key) && mLockPatternUtils.isSecure(UserHandle.myUserId())) {
// Show the disabling FRP warning only when the user is switching from a secure
// unlock method to an insecure one
showFactoryResetProtectionWarningDialog(key);
@@ -268,10 +269,10 @@ public class ChooseLockGeneric extends SettingsActivity {
}
private String getKeyForCurrent() {
- if (mLockPatternUtils.isLockScreenDisabled()) {
+ if (mLockPatternUtils.isLockScreenDisabled(UserHandle.myUserId())) {
return KEY_UNLOCK_SET_OFF;
}
- switch (mLockPatternUtils.getKeyguardStoredPasswordQuality()) {
+ switch (mLockPatternUtils.getKeyguardStoredPasswordQuality(UserHandle.myUserId())) {
case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
return KEY_UNLOCK_SET_PATTERN;
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
@@ -474,8 +475,9 @@ public class ChooseLockGeneric extends SettingsActivity {
}
startActivityForResult(intent, CHOOSE_LOCK_REQUEST);
} else if (quality == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
- mChooseLockSettingsHelper.utils().clearLock();
- mChooseLockSettingsHelper.utils().setLockScreenDisabled(disabled);
+ mChooseLockSettingsHelper.utils().clearLock(UserHandle.myUserId());
+ mChooseLockSettingsHelper.utils().setLockScreenDisabled(disabled,
+ UserHandle.myUserId());
removeAllFingerprintTemplates();
getActivity().setResult(Activity.RESULT_OK);
finish();
@@ -502,7 +504,7 @@ public class ChooseLockGeneric extends SettingsActivity {
}
private int getResIdForFactoryResetProtectionWarningTitle() {
- switch (mLockPatternUtils.getKeyguardStoredPasswordQuality()) {
+ switch (mLockPatternUtils.getKeyguardStoredPasswordQuality(UserHandle.myUserId())) {
case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
return R.string.unlock_disable_lock_pattern_summary;
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
diff --git a/src/com/android/settings/ChooseLockPassword.java b/src/com/android/settings/ChooseLockPassword.java
index e15d3fc4e..0817eeb0e 100644
--- a/src/com/android/settings/ChooseLockPassword.java
+++ b/src/com/android/settings/ChooseLockPassword.java
@@ -31,6 +31,7 @@ import android.inputmethodservice.KeyboardView;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
+import android.os.UserHandle;
import android.text.Editable;
import android.text.InputType;
import android.text.Selection;
@@ -200,24 +201,31 @@ public class ChooseLockPassword extends SettingsActivity {
throw new SecurityException("Fragment contained in wrong activity");
}
mRequestedQuality = Math.max(intent.getIntExtra(LockPatternUtils.PASSWORD_TYPE_KEY,
- mRequestedQuality), mLockPatternUtils.getRequestedPasswordQuality());
+ mRequestedQuality), mLockPatternUtils.getRequestedPasswordQuality(
+ UserHandle.myUserId()));
mPasswordMinLength = Math.max(Math.max(
LockPatternUtils.MIN_LOCK_PASSWORD_SIZE,
intent.getIntExtra(PASSWORD_MIN_KEY, mPasswordMinLength)),
- mLockPatternUtils.getRequestedMinimumPasswordLength());
+ mLockPatternUtils.getRequestedMinimumPasswordLength(UserHandle.myUserId()));
mPasswordMaxLength = intent.getIntExtra(PASSWORD_MAX_KEY, mPasswordMaxLength);
mPasswordMinLetters = Math.max(intent.getIntExtra(PASSWORD_MIN_LETTERS_KEY,
- mPasswordMinLetters), mLockPatternUtils.getRequestedPasswordMinimumLetters());
+ mPasswordMinLetters), mLockPatternUtils.getRequestedPasswordMinimumLetters(
+ UserHandle.myUserId()));
mPasswordMinUpperCase = Math.max(intent.getIntExtra(PASSWORD_MIN_UPPERCASE_KEY,
- mPasswordMinUpperCase), mLockPatternUtils.getRequestedPasswordMinimumUpperCase());
+ mPasswordMinUpperCase), mLockPatternUtils.getRequestedPasswordMinimumUpperCase(
+ UserHandle.myUserId()));
mPasswordMinLowerCase = Math.max(intent.getIntExtra(PASSWORD_MIN_LOWERCASE_KEY,
- mPasswordMinLowerCase), mLockPatternUtils.getRequestedPasswordMinimumLowerCase());
+ mPasswordMinLowerCase), mLockPatternUtils.getRequestedPasswordMinimumLowerCase(
+ UserHandle.myUserId()));
mPasswordMinNumeric = Math.max(intent.getIntExtra(PASSWORD_MIN_NUMERIC_KEY,
- mPasswordMinNumeric), mLockPatternUtils.getRequestedPasswordMinimumNumeric());
+ mPasswordMinNumeric), mLockPatternUtils.getRequestedPasswordMinimumNumeric(
+ UserHandle.myUserId()));
mPasswordMinSymbols = Math.max(intent.getIntExtra(PASSWORD_MIN_SYMBOLS_KEY,
- mPasswordMinSymbols), mLockPatternUtils.getRequestedPasswordMinimumSymbols());
+ mPasswordMinSymbols), mLockPatternUtils.getRequestedPasswordMinimumSymbols(
+ UserHandle.myUserId()));
mPasswordMinNonLetter = Math.max(intent.getIntExtra(PASSWORD_MIN_NONLETTER_KEY,
- mPasswordMinNonLetter), mLockPatternUtils.getRequestedPasswordMinimumNonLetter());
+ mPasswordMinNonLetter), mLockPatternUtils.getRequestedPasswordMinimumNonLetter(
+ UserHandle.myUserId()));
mChooseLockSettingsHelper = new ChooseLockSettingsHelper(getActivity());
}
@@ -448,7 +456,7 @@ public class ChooseLockPassword extends SettingsActivity {
return getString(R.string.lockpassword_password_requires_digit);
}
}
- if(mLockPatternUtils.checkPasswordHistory(password)) {
+ if(mLockPatternUtils.checkPasswordHistory(password, UserHandle.myUserId())) {
return getString(mIsAlphaMode ? R.string.lockpassword_password_recently_used
: R.string.lockpassword_pin_recently_used);
}
@@ -473,15 +481,17 @@ public class ChooseLockPassword extends SettingsActivity {
}
} else if (mUiStage == Stage.NeedToConfirm) {
if (mFirstPin.equals(pin)) {
- boolean wasSecureBefore = mLockPatternUtils.isSecure();
+ boolean wasSecureBefore = mLockPatternUtils.isSecure(UserHandle.myUserId());
final boolean required = getActivity().getIntent().getBooleanExtra(
EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, true);
mLockPatternUtils.setCredentialRequiredToDecrypt(required);
- mLockPatternUtils.saveLockPassword(pin, mCurrentPassword, mRequestedQuality);
+ mLockPatternUtils.saveLockPassword(pin, mCurrentPassword, mRequestedQuality,
+ UserHandle.myUserId());
if (mHasChallenge) {
Intent intent = new Intent();
- byte[] token = mLockPatternUtils.verifyPassword(pin, mChallenge);
+ byte[] token = mLockPatternUtils.verifyPassword(pin, mChallenge,
+ UserHandle.myUserId());
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token);
getActivity().setResult(RESULT_FINISHED, intent);
} else {
diff --git a/src/com/android/settings/ChooseLockPattern.java b/src/com/android/settings/ChooseLockPattern.java
index e3b7d4b61..99e8d2490 100644
--- a/src/com/android/settings/ChooseLockPattern.java
+++ b/src/com/android/settings/ChooseLockPattern.java
@@ -31,6 +31,7 @@ import android.app.Fragment;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
+import android.os.UserHandle;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
@@ -603,18 +604,18 @@ public class ChooseLockPattern extends SettingsActivity {
private void saveChosenPatternAndFinish() {
if (mDone) return;
LockPatternUtils utils = mChooseLockSettingsHelper.utils();
- final boolean lockVirgin = !utils.isPatternEverChosen();
+ final boolean lockVirgin = !utils.isPatternEverChosen(UserHandle.myUserId());
- boolean wasSecureBefore = utils.isSecure();
+ boolean wasSecureBefore = utils.isSecure(UserHandle.myUserId());
final boolean required = getActivity().getIntent().getBooleanExtra(
EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, true);
utils.setCredentialRequiredToDecrypt(required);
- utils.saveLockPattern(mChosenPattern, mCurrentPattern);
+ utils.saveLockPattern(mChosenPattern, mCurrentPattern, UserHandle.myUserId());
if (lockVirgin) {
- utils.setVisiblePatternEnabled(true);
+ utils.setVisiblePatternEnabled(true, UserHandle.myUserId());
}
if (!wasSecureBefore) {
@@ -623,7 +624,8 @@ public class ChooseLockPattern extends SettingsActivity {
if (mHasChallenge) {
Intent intent = new Intent();
- byte[] token = utils.verifyPattern(mChosenPattern, mChallenge);
+ byte[] token = utils.verifyPattern(mChosenPattern, mChallenge,
+ UserHandle.myUserId());
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token);
getActivity().setResult(RESULT_FINISHED, intent);
} else {
diff --git a/src/com/android/settings/ChooseLockSettingsHelper.java b/src/com/android/settings/ChooseLockSettingsHelper.java
index c9f20ffa8..8b8d97647 100644
--- a/src/com/android/settings/ChooseLockSettingsHelper.java
+++ b/src/com/android/settings/ChooseLockSettingsHelper.java
@@ -21,6 +21,7 @@ import android.app.Activity;
import android.app.Fragment;
import android.app.admin.DevicePolicyManager;
import android.content.Intent;
+import android.os.UserHandle;
import com.android.internal.widget.LockPatternUtils;
@@ -116,7 +117,7 @@ public final class ChooseLockSettingsHelper {
boolean returnCredentials, boolean external, boolean hasChallenge,
long challenge) {
boolean launched = false;
- switch (mLockPatternUtils.getKeyguardStoredPasswordQuality()) {
+ switch (mLockPatternUtils.getKeyguardStoredPasswordQuality(UserHandle.myUserId())) {
case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
launched = launchConfirmationActivity(request, title, header, description,
returnCredentials || hasChallenge
diff --git a/src/com/android/settings/ConfirmLockPassword.java b/src/com/android/settings/ConfirmLockPassword.java
index bec3a45a2..099408692 100644
--- a/src/com/android/settings/ConfirmLockPassword.java
+++ b/src/com/android/settings/ConfirmLockPassword.java
@@ -17,6 +17,7 @@
package com.android.settings;
import android.annotation.Nullable;
+import android.os.UserHandle;
import android.text.TextUtils;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.widget.LockPatternUtils;
@@ -90,7 +91,8 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
- final int storedQuality = mLockPatternUtils.getKeyguardStoredPasswordQuality();
+ final int storedQuality = mLockPatternUtils.getKeyguardStoredPasswordQuality(
+ UserHandle.myUserId());
View view = inflater.inflate(R.layout.confirm_lock_password, null);
mPasswordEntry = (TextView) view.findViewById(R.id.password_entry);
@@ -156,7 +158,7 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
@Override
public void onResume() {
super.onResume();
- long deadline = mLockPatternUtils.getLockoutAttemptDeadline();
+ long deadline = mLockPatternUtils.getLockoutAttemptDeadline(UserHandle.myUserId());
if (deadline != 0) {
handleAttemptLockout(deadline);
}
@@ -185,13 +187,14 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
if (getActivity() instanceof ConfirmLockPassword.InternalActivity) {
long challenge = getActivity().getIntent().getLongExtra(
ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0);
- byte[] token = mLockPatternUtils.verifyPassword(pin, challenge);
+ byte[] token = mLockPatternUtils.verifyPassword(pin, challenge,
+ UserHandle.myUserId());
if (token != null) {
matched = true;
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token);
}
}
- } else if (mLockPatternUtils.checkPassword(pin)) {
+ } else if (mLockPatternUtils.checkPassword(pin, UserHandle.myUserId())) {
matched = true;
if (getActivity() instanceof ConfirmLockPassword.InternalActivity) {
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_TYPE,
@@ -206,7 +209,8 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
getActivity().finish();
} else {
if (++mNumWrongConfirmAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) {
- long deadline = mLockPatternUtils.setLockoutAttemptDeadline();
+ long deadline = mLockPatternUtils.setLockoutAttemptDeadline(
+ UserHandle.myUserId());
handleAttemptLockout(deadline);
} else {
showError(getErrorMessage());
diff --git a/src/com/android/settings/ConfirmLockPattern.java b/src/com/android/settings/ConfirmLockPattern.java
index 420a7f8d0..2d0d11778 100644
--- a/src/com/android/settings/ConfirmLockPattern.java
+++ b/src/com/android/settings/ConfirmLockPattern.java
@@ -28,6 +28,7 @@ import android.content.Intent;
import android.os.CountDownTimer;
import android.os.SystemClock;
import android.os.Bundle;
+import android.os.UserHandle;
import android.os.storage.StorageManager;
import android.view.MenuItem;
import android.widget.TextView;
@@ -135,7 +136,7 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
// on first launch, if no lock pattern is set, then finish with
// success (don't want user to get stuck confirming something that
// doesn't exist).
- if (!mLockPatternUtils.isLockPatternEnabled()) {
+ if (!mLockPatternUtils.isLockPatternEnabled(UserHandle.myUserId())) {
getActivity().setResult(Activity.RESULT_OK);
getActivity().finish();
}
@@ -168,7 +169,7 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
super.onResume();
// if the user is currently locked out, enforce it.
- long deadline = mLockPatternUtils.getLockoutAttemptDeadline();
+ long deadline = mLockPatternUtils.getLockoutAttemptDeadline(UserHandle.myUserId());
if (deadline != 0) {
handleAttemptLockout(deadline);
} else if (!mLockPatternView.isEnabled()) {
@@ -276,13 +277,14 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
if (getActivity() instanceof ConfirmLockPattern.InternalActivity) {
long challenge = getActivity().getIntent().getLongExtra(
ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0);
- byte[] token = mLockPatternUtils.verifyPattern(pattern, challenge);
+ byte[] token = mLockPatternUtils.verifyPattern(pattern, challenge,
+ UserHandle.myUserId());
if (token != null) {
matched = true;
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token);
}
}
- } else if (mLockPatternUtils.checkPattern(pattern)) {
+ } else if (mLockPatternUtils.checkPattern(pattern, UserHandle.myUserId())) {
matched = true;
if (getActivity() instanceof ConfirmLockPattern.InternalActivity) {
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_TYPE,
@@ -300,7 +302,8 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
if (pattern.size() >= LockPatternUtils.MIN_PATTERN_REGISTER_FAIL &&
++mNumWrongConfirmAttempts
>= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) {
- long deadline = mLockPatternUtils.setLockoutAttemptDeadline();
+ long deadline = mLockPatternUtils.setLockoutAttemptDeadline(
+ UserHandle.myUserId());
handleAttemptLockout(deadline);
} else {
updateStage(Stage.NeedToUnlockWrong);
diff --git a/src/com/android/settings/CredentialStorage.java b/src/com/android/settings/CredentialStorage.java
index 8506964d8..81e0a4641 100644
--- a/src/com/android/settings/CredentialStorage.java
+++ b/src/com/android/settings/CredentialStorage.java
@@ -200,7 +200,8 @@ public final class CredentialStorage extends Activity {
* Returns true if the currently set key guard matches our minimum quality requirements.
*/
private boolean checkKeyGuardQuality() {
- int quality = new LockPatternUtils(this).getActivePasswordQuality();
+ int quality = new LockPatternUtils(this).getActivePasswordQuality(
+ UserHandle.myUserId());
return (quality >= MIN_PASSWORD_QUALITY);
}
diff --git a/src/com/android/settings/CryptKeeperConfirm.java b/src/com/android/settings/CryptKeeperConfirm.java
index 77a1c4563..513a42871 100644
--- a/src/com/android/settings/CryptKeeperConfirm.java
+++ b/src/com/android/settings/CryptKeeperConfirm.java
@@ -120,8 +120,10 @@ public class CryptKeeperConfirm extends InstrumentedFragment {
// 1. The owner info.
LockPatternUtils utils = new LockPatternUtils(getActivity());
- utils.setVisiblePatternEnabled(utils.isVisiblePatternEnabled());
- if (utils.isOwnerInfoEnabled()) {
+ utils.setVisiblePatternEnabled(
+ utils.isVisiblePatternEnabled(UserHandle.USER_OWNER),
+ UserHandle.USER_OWNER);
+ if (utils.isOwnerInfoEnabled(UserHandle.USER_OWNER)) {
utils.setOwnerInfo(utils.getOwnerInfo(UserHandle.USER_OWNER),
UserHandle.USER_OWNER);
}
diff --git a/src/com/android/settings/CryptKeeperSettings.java b/src/com/android/settings/CryptKeeperSettings.java
index 2e4aeb89f..c5a06eb64 100644
--- a/src/com/android/settings/CryptKeeperSettings.java
+++ b/src/com/android/settings/CryptKeeperSettings.java
@@ -27,6 +27,7 @@ import android.content.IntentFilter;
import android.content.res.Resources;
import android.os.BatteryManager;
import android.os.Bundle;
+import android.os.UserHandle;
import android.os.storage.StorageManager;
import android.preference.Preference;
import android.text.TextUtils;
@@ -160,7 +161,7 @@ public class CryptKeeperSettings extends InstrumentedFragment {
Resources res = getActivity().getResources();
ChooseLockSettingsHelper helper = new ChooseLockSettingsHelper(getActivity(), this);
- if (helper.utils().getKeyguardStoredPasswordQuality()
+ if (helper.utils().getKeyguardStoredPasswordQuality(UserHandle.myUserId())
== DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
showFinalConfirmation(StorageManager.CRYPT_TYPE_DEFAULT, "");
return true;
diff --git a/src/com/android/settings/EncryptionInterstitial.java b/src/com/android/settings/EncryptionInterstitial.java
index 9b6444cde..794005b0b 100644
--- a/src/com/android/settings/EncryptionInterstitial.java
+++ b/src/com/android/settings/EncryptionInterstitial.java
@@ -33,6 +33,7 @@ import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.os.Bundle;
+import android.os.UserHandle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -149,7 +150,7 @@ public class EncryptionInterstitial extends SettingsActivity {
switch(dialogId) {
case ACCESSIBILITY_WARNING_DIALOG: {
final int quality = new LockPatternUtils(getActivity())
- .getKeyguardStoredPasswordQuality();
+ .getKeyguardStoredPasswordQuality(UserHandle.myUserId());
final int titleId;
final int messageId;
switch (quality) {
diff --git a/src/com/android/settings/OwnerInfoSettings.java b/src/com/android/settings/OwnerInfoSettings.java
index 56da63768..9cc78ea2c 100644
--- a/src/com/android/settings/OwnerInfoSettings.java
+++ b/src/com/android/settings/OwnerInfoSettings.java
@@ -101,7 +101,7 @@ public class OwnerInfoSettings extends DialogFragment implements OnClickListener
public void onClick(DialogInterface dialog, int which) {
if (which == AlertDialog.BUTTON_POSITIVE) {
String info = mOwnerInfo.getText().toString();
- mLockPatternUtils.setOwnerInfoEnabled(!TextUtils.isEmpty(info));
+ mLockPatternUtils.setOwnerInfoEnabled(!TextUtils.isEmpty(info), mUserId);
mLockPatternUtils.setOwnerInfo(info, mUserId);
if (getTargetFragment() instanceof SecuritySettings) {
diff --git a/src/com/android/settings/ScreenPinningSettings.java b/src/com/android/settings/ScreenPinningSettings.java
index adda01b00..cfeddbbcd 100644
--- a/src/com/android/settings/ScreenPinningSettings.java
+++ b/src/com/android/settings/ScreenPinningSettings.java
@@ -20,6 +20,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
+import android.os.UserHandle;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.PreferenceScreen;
@@ -103,8 +104,9 @@ public class ScreenPinningSettings extends SettingsPreferenceFragment
private boolean setScreenLockUsed(boolean isEnabled) {
if (isEnabled) {
LockPatternUtils lockPatternUtils = new LockPatternUtils(getActivity());
- if (lockPatternUtils.getKeyguardStoredPasswordQuality()
- == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
+ int passwordQuality = lockPatternUtils
+ .getKeyguardStoredPasswordQuality(UserHandle.myUserId());
+ if (passwordQuality == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
Intent chooseLockIntent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
chooseLockIntent.putExtra(
ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY,
@@ -123,7 +125,8 @@ public class ScreenPinningSettings extends SettingsPreferenceFragment
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CHANGE_LOCK_METHOD_REQUEST) {
LockPatternUtils lockPatternUtils = new LockPatternUtils(getActivity());
- boolean validPassQuality = lockPatternUtils.getKeyguardStoredPasswordQuality()
+ boolean validPassQuality = lockPatternUtils.getKeyguardStoredPasswordQuality(
+ UserHandle.myUserId())
!= DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
setScreenLockUsed(validPassQuality);
// Make sure the screen updates.
@@ -132,7 +135,8 @@ public class ScreenPinningSettings extends SettingsPreferenceFragment
}
private int getCurrentSecurityTitle() {
- int quality = mLockPatternUtils.getKeyguardStoredPasswordQuality();
+ int quality = mLockPatternUtils.getKeyguardStoredPasswordQuality(
+ UserHandle.myUserId());
switch (quality) {
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
@@ -142,7 +146,7 @@ public class ScreenPinningSettings extends SettingsPreferenceFragment
case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
return R.string.screen_pinning_unlock_password;
case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
- if (mLockPatternUtils.isLockPatternEnabled()) {
+ if (mLockPatternUtils.isLockPatternEnabled(UserHandle.myUserId())) {
return R.string.screen_pinning_unlock_pattern;
}
}
diff --git a/src/com/android/settings/SecuritySettings.java b/src/com/android/settings/SecuritySettings.java
index 132281fa0..1c0f445ba 100644
--- a/src/com/android/settings/SecuritySettings.java
+++ b/src/com/android/settings/SecuritySettings.java
@@ -111,6 +111,8 @@ public class SecuritySettings extends SettingsPreferenceFragment
// Only allow one trust agent on the platform.
private static final boolean ONLY_ONE_TRUST_AGENT = true;
+ private static final int MY_USER_ID = UserHandle.myUserId();
+
private DevicePolicyManager mDPM;
private SubscriptionManager mSubscriptionManager;
@@ -160,14 +162,14 @@ public class SecuritySettings extends SettingsPreferenceFragment
private static int getResIdForLockUnlockScreen(Context context,
LockPatternUtils lockPatternUtils) {
int resid = 0;
- if (!lockPatternUtils.isSecure()) {
- if (lockPatternUtils.isLockScreenDisabled()) {
+ if (!lockPatternUtils.isSecure(MY_USER_ID)) {
+ if (lockPatternUtils.isLockScreenDisabled(MY_USER_ID)) {
resid = R.xml.security_settings_lockscreen;
} else {
resid = R.xml.security_settings_chooser;
}
} else {
- switch (lockPatternUtils.getKeyguardStoredPasswordQuality()) {
+ switch (lockPatternUtils.getKeyguardStoredPasswordQuality(MY_USER_ID)) {
case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
resid = R.xml.security_settings_pattern;
break;
@@ -204,7 +206,7 @@ public class SecuritySettings extends SettingsPreferenceFragment
addPreferencesFromResource(resid);
// Add options for device encryption
- mIsPrimary = UserHandle.myUserId() == UserHandle.USER_OWNER;
+ mIsPrimary = MY_USER_ID == UserHandle.USER_OWNER;
mOwnerInfoPref = findPreference(KEY_OWNER_INFO_SETTINGS);
if (mOwnerInfoPref != null) {
@@ -304,7 +306,7 @@ public class SecuritySettings extends SettingsPreferenceFragment
mToggleAppInstallation.setChecked(isNonMarketAppsAllowed());
// Side loading of apps.
// Disable for restricted profiles. For others, check if policy disallows it.
- mToggleAppInstallation.setEnabled(!um.getUserInfo(UserHandle.myUserId()).isRestricted());
+ mToggleAppInstallation.setEnabled(!um.getUserInfo(MY_USER_ID).isRestricted());
if (um.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES)
|| um.hasUserRestriction(UserManager.DISALLOW_INSTALL_APPS)) {
mToggleAppInstallation.setEnabled(false);
@@ -315,7 +317,7 @@ public class SecuritySettings extends SettingsPreferenceFragment
(PreferenceGroup)root.findPreference(KEY_ADVANCED_SECURITY);
if (advancedCategory != null) {
Preference manageAgents = advancedCategory.findPreference(KEY_MANAGE_TRUST_AGENTS);
- if (manageAgents != null && !mLockPatternUtils.isSecure()) {
+ if (manageAgents != null && !mLockPatternUtils.isSecure(MY_USER_ID)) {
manageAgents.setEnabled(false);
manageAgents.setSummary(R.string.disabled_because_no_backup_security);
}
@@ -348,7 +350,8 @@ public class SecuritySettings extends SettingsPreferenceFragment
final List<Fingerprint> items = fpm.getEnrolledFingerprints();
final int fingerprintCount = items != null ? items.size() : 0;
final String clazz;
- boolean hasPassword = mChooseLockSettingsHelper.utils().getActivePasswordQuality()
+ boolean hasPassword = mChooseLockSettingsHelper.utils().getActivePasswordQuality(
+ MY_USER_ID)
!= DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
if (fingerprintCount > 0) {
fingerprintPreference.setSummary(getResources().getQuantityString(
@@ -368,7 +371,7 @@ public class SecuritySettings extends SettingsPreferenceFragment
}
private void addTrustAgentSettings(PreferenceGroup securityCategory) {
- final boolean hasSecurity = mLockPatternUtils.isSecure();
+ final boolean hasSecurity = mLockPatternUtils.isSecure(MY_USER_ID);
ArrayList<TrustAgentComponentInfo> agents =
getActiveTrustAgents(getPackageManager(), mLockPatternUtils, mDPM);
for (int i = 0; i < agents.size(); i++) {
@@ -438,7 +441,7 @@ public class SecuritySettings extends SettingsPreferenceFragment
ArrayList<TrustAgentComponentInfo> result = new ArrayList<TrustAgentComponentInfo>();
List<ResolveInfo> resolveInfos = pm.queryIntentServices(TRUST_AGENT_INTENT,
PackageManager.GET_META_DATA);
- List<ComponentName> enabledTrustAgents = utils.getEnabledTrustAgents();
+ List<ComponentName> enabledTrustAgents = utils.getEnabledTrustAgents(MY_USER_ID);
boolean disableTrustAgents = (dpm.getKeyguardDisabledFeatures(null)
& DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0;
@@ -597,10 +600,12 @@ public class SecuritySettings extends SettingsPreferenceFragment
final LockPatternUtils lockPatternUtils = mChooseLockSettingsHelper.utils();
if (mVisiblePattern != null) {
- mVisiblePattern.setChecked(lockPatternUtils.isVisiblePatternEnabled());
+ mVisiblePattern.setChecked(lockPatternUtils.isVisiblePatternEnabled(
+ MY_USER_ID));
}
if (mPowerButtonInstantlyLocks != null) {
- mPowerButtonInstantlyLocks.setChecked(lockPatternUtils.getPowerButtonInstantlyLocks());
+ mPowerButtonInstantlyLocks.setChecked(lockPatternUtils.getPowerButtonInstantlyLocks(
+ MY_USER_ID));
}
if (mShowPassword != null) {
@@ -617,8 +622,8 @@ public class SecuritySettings extends SettingsPreferenceFragment
public void updateOwnerInfo() {
if (mOwnerInfoPref != null) {
- mOwnerInfoPref.setSummary(mLockPatternUtils.isOwnerInfoEnabled()
- ? mLockPatternUtils.getOwnerInfo(UserHandle.myUserId())
+ mOwnerInfoPref.setSummary(mLockPatternUtils.isOwnerInfoEnabled(MY_USER_ID)
+ ? mLockPatternUtils.getOwnerInfo(MY_USER_ID)
: getString(R.string.owner_info_settings_summary));
}
}
@@ -678,9 +683,9 @@ public class SecuritySettings extends SettingsPreferenceFragment
}
updateLockAfterPreferenceSummary();
} else if (KEY_VISIBLE_PATTERN.equals(key)) {
- lockPatternUtils.setVisiblePatternEnabled((Boolean) value);
+ lockPatternUtils.setVisiblePatternEnabled((Boolean) value, MY_USER_ID);
} else if (KEY_POWER_INSTANTLY_LOCKS.equals(key)) {
- mLockPatternUtils.setPowerButtonInstantlyLocks((Boolean) value);
+ mLockPatternUtils.setPowerButtonInstantlyLocks((Boolean) value, MY_USER_ID);
} else if (KEY_SHOW_PASSWORD.equals(key)) {
Settings.System.putInt(getContentResolver(), Settings.System.TEXT_SHOW_PASSWORD,
((Boolean) value) ? 1 : 0);
@@ -715,7 +720,7 @@ public class SecuritySettings extends SettingsPreferenceFragment
public SecuritySearchIndexProvider() {
super();
- mIsPrimary = UserHandle.myUserId() == UserHandle.USER_OWNER;
+ mIsPrimary = MY_USER_ID == UserHandle.USER_OWNER;
}
@Override
@@ -800,7 +805,7 @@ public class SecuritySettings extends SettingsPreferenceFragment
// Advanced
final LockPatternUtils lockPatternUtils = new LockPatternUtils(context);
- if (lockPatternUtils.isSecure()) {
+ if (lockPatternUtils.isSecure(MY_USER_ID)) {
ArrayList<TrustAgentComponentInfo> agents =
getActiveTrustAgents(context.getPackageManager(), lockPatternUtils,
context.getSystemService(DevicePolicyManager.class));
@@ -835,7 +840,7 @@ public class SecuritySettings extends SettingsPreferenceFragment
}
// TrustAgent settings disappear when the user has no primary security.
- if (!lockPatternUtils.isSecure()) {
+ if (!lockPatternUtils.isSecure(MY_USER_ID)) {
keys.add(KEY_TRUST_AGENT);
keys.add(KEY_MANAGE_TRUST_AGENTS);
}
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index ba0803645..88c831696 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -33,7 +33,8 @@ public class Settings extends SettingsActivity {
public static class VpnSettingsActivity extends SettingsActivity { /* empty */ }
public static class DateTimeSettingsActivity extends SettingsActivity { /* empty */ }
public static class StorageSettingsActivity extends SettingsActivity { /* empty */ }
- public static class StorageVolumeSettingsActivity extends SettingsActivity { /* empty */ }
+ public static class PublicVolumeSettingsActivity extends SettingsActivity { /* empty */ }
+ public static class PrivateVolumeForgetActivity extends SettingsActivity { /* empty */ }
public static class WifiSettingsActivity extends SettingsActivity { /* empty */ }
public static class WifiP2pSettingsActivity extends SettingsActivity { /* empty */ }
public static class InputMethodAndLanguageSettingsActivity extends SettingsActivity { /* empty */ }
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index ee2b1b4ce..5e1acb176 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -83,6 +83,7 @@ import com.android.settings.dashboard.DashboardSummary;
import com.android.settings.dashboard.DashboardTile;
import com.android.settings.dashboard.NoHomeDialogFragment;
import com.android.settings.dashboard.SearchResultsSummary;
+import com.android.settings.deviceinfo.PrivateVolumeForget;
import com.android.settings.deviceinfo.PublicVolumeSettings;
import com.android.settings.deviceinfo.StorageSettings;
import com.android.settings.deviceinfo.UsbSettings;
@@ -310,6 +311,7 @@ public class SettingsActivity extends Activity
TextToSpeechSettings.class.getName(),
StorageSettings.class.getName(),
PublicVolumeSettings.class.getName(),
+ PrivateVolumeForget.class.getName(),
DevelopmentSettings.class.getName(),
UsbSettings.class.getName(),
AndroidBeam.class.getName(),
diff --git a/src/com/android/settings/TrustAgentSettings.java b/src/com/android/settings/TrustAgentSettings.java
index 4c6b4ee79..37a86ebb1 100644
--- a/src/com/android/settings/TrustAgentSettings.java
+++ b/src/com/android/settings/TrustAgentSettings.java
@@ -26,6 +26,7 @@ import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
+import android.os.UserHandle;
import android.preference.Preference;
import android.preference.PreferenceGroup;
import android.preference.SwitchPreference;
@@ -120,14 +121,16 @@ public class TrustAgentSettings extends SettingsPreferenceFragment implements
}
private void loadActiveAgents() {
- List<ComponentName> activeTrustAgents = mLockPatternUtils.getEnabledTrustAgents();
+ List<ComponentName> activeTrustAgents = mLockPatternUtils.getEnabledTrustAgents(
+ UserHandle.myUserId());
if (activeTrustAgents != null) {
mActiveAgents.addAll(activeTrustAgents);
}
}
private void saveActiveAgents() {
- mLockPatternUtils.setEnabledTrustAgents(mActiveAgents);
+ mLockPatternUtils.setEnabledTrustAgents(mActiveAgents,
+ UserHandle.myUserId());
}
ArrayMap<ComponentName, AgentInfo> findAvailableTrustAgents() {
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index d05160c38..4ddba8052 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -22,9 +22,11 @@ import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.AlertDialog;
+import android.app.AppGlobals;
import android.app.Dialog;
import android.app.Fragment;
import android.app.IActivityManager;
+import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
@@ -32,6 +34,7 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
@@ -1153,4 +1156,27 @@ public final class Utils {
view.setVisibility(shown ? View.VISIBLE : View.INVISIBLE);
}
}
-}
+
+ /**
+ * Returns the application info of the currently installed MDM package.
+ */
+ public static ApplicationInfo getAdminApplicationInfo(Context context, int profileId) {
+ DevicePolicyManager dpm =
+ (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
+ ComponentName mdmPackage = dpm.getProfileOwnerAsUser(profileId);
+ if (mdmPackage == null) {
+ return null;
+ }
+ String mdmPackageName = mdmPackage.getPackageName();
+ try {
+ IPackageManager ipm = AppGlobals.getPackageManager();
+ ApplicationInfo mdmApplicationInfo =
+ ipm.getApplicationInfo(mdmPackageName, 0, profileId);
+ return mdmApplicationInfo;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error while retrieving application info for package " + mdmPackageName
+ + ", userId " + profileId, e);
+ return null;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
index 609253292..16389cb80 100644
--- a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
@@ -29,6 +29,7 @@ import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
+import android.os.UserHandle;
import android.provider.Settings;
import android.text.TextUtils;
import android.view.LayoutInflater;
@@ -368,7 +369,7 @@ public class ToggleAccessibilityServicePreferenceFragment
private String createConfirmCredentialReasonMessage() {
int resId = R.string.enable_service_password_reason;
- switch (mLockPatternUtils.getKeyguardStoredPasswordQuality()) {
+ switch (mLockPatternUtils.getKeyguardStoredPasswordQuality(UserHandle.myUserId())) {
case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING: {
resId = R.string.enable_service_pattern_reason;
} break;
diff --git a/src/com/android/settings/applications/DefaultBrowserPreference.java b/src/com/android/settings/applications/DefaultBrowserPreference.java
index da7f112d3..44797898f 100644
--- a/src/com/android/settings/applications/DefaultBrowserPreference.java
+++ b/src/com/android/settings/applications/DefaultBrowserPreference.java
@@ -56,7 +56,8 @@ public class DefaultBrowserPreference extends AppListPreference {
intent.setData(Uri.parse("http:"));
// Resolve that intent and check that the handleAllWebDataURI boolean is set
- List<ResolveInfo> list = mPm.queryIntentActivitiesAsUser(intent, 0, UserHandle.myUserId());
+ List<ResolveInfo> list = mPm.queryIntentActivitiesAsUser(intent, PackageManager.MATCH_ALL,
+ UserHandle.myUserId());
final int count = list.size();
for (int i=0; i<count; i++) {
diff --git a/src/com/android/settings/applications/DefaultDialerPreference.java b/src/com/android/settings/applications/DefaultDialerPreference.java
index 8de45328f..705e4ef1a 100644
--- a/src/com/android/settings/applications/DefaultDialerPreference.java
+++ b/src/com/android/settings/applications/DefaultDialerPreference.java
@@ -16,7 +16,6 @@
package com.android.settings.applications;
-import android.content.ComponentName;
import android.content.Context;
import android.os.UserManager;
import android.telecom.DefaultDialerManager;
@@ -49,22 +48,18 @@ public class DefaultDialerPreference extends AppListPreference {
}
private void loadDialerApps() {
- List<ComponentName> dialerComponents =
+ List<String> dialerPackages =
DefaultDialerManager.getInstalledDialerApplications(getContext());
- final String[] dialers = new String[dialerComponents.size()];
- for (int i = 0; i < dialerComponents.size(); i++) {
- dialers[i] = dialerComponents.get(i).getPackageName();
+ final String[] dialers = new String[dialerPackages.size()];
+ for (int i = 0; i < dialerPackages.size(); i++) {
+ dialers[i] = dialerPackages.get(i);
}
setPackageNames(dialers, getDefaultPackage());
}
private String getDefaultPackage() {
- ComponentName appName = DefaultDialerManager.getDefaultDialerApplication(getContext());
- if (appName != null) {
- return appName.getPackageName();
- }
- return null;
+ return DefaultDialerManager.getDefaultDialerApplication(getContext());
}
public static boolean isAvailable(Context context) {
diff --git a/src/com/android/settings/deviceinfo/PrivateVolumeForget.java b/src/com/android/settings/deviceinfo/PrivateVolumeForget.java
new file mode 100644
index 000000000..c8b04e31f
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/PrivateVolumeForget.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2015 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.os.Bundle;
+import android.os.storage.StorageManager;
+import android.os.storage.VolumeRecord;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.TextView;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.settings.InstrumentedFragment;
+import com.android.settings.R;
+
+public class PrivateVolumeForget extends InstrumentedFragment {
+ private VolumeRecord mRecord;
+
+ @Override
+ protected int getMetricsCategory() {
+ return MetricsLogger.DEVICEINFO_STORAGE;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ final StorageManager storage = getActivity().getSystemService(StorageManager.class);
+ final String fsUuid = getArguments().getString(VolumeRecord.EXTRA_FS_UUID);
+ mRecord = storage.findRecordByUuid(fsUuid);
+
+ final View view = inflater.inflate(R.layout.storage_internal_forget, container, false);
+ final TextView body = (TextView) view.findViewById(R.id.body);
+ final Button confirm = (Button) view.findViewById(R.id.confirm);
+
+ body.setText(TextUtils.expandTemplate(getText(R.string.storage_internal_forget_details),
+ mRecord.getNickname()));
+ confirm.setOnClickListener(mConfirmListener);
+
+ return view;
+ }
+
+ private final OnClickListener mConfirmListener = new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ final StorageManager storage = getActivity().getSystemService(StorageManager.class);
+ storage.forgetVolume(mRecord.getFsUuid());
+ getActivity().finish();
+ }
+ };
+}
diff --git a/src/com/android/settings/deviceinfo/PrivateVolumeFormatConfirm.java b/src/com/android/settings/deviceinfo/PrivateVolumeFormat.java
index 666a91871..e16778fac 100644
--- a/src/com/android/settings/deviceinfo/PrivateVolumeFormatConfirm.java
+++ b/src/com/android/settings/deviceinfo/PrivateVolumeFormat.java
@@ -33,7 +33,7 @@ import com.android.internal.logging.MetricsLogger;
import com.android.settings.InstrumentedFragment;
import com.android.settings.R;
-public class PrivateVolumeFormatConfirm extends InstrumentedFragment {
+public class PrivateVolumeFormat extends InstrumentedFragment {
private VolumeInfo mVolume;
private DiskInfo mDisk;
@@ -66,7 +66,7 @@ public class PrivateVolumeFormatConfirm extends InstrumentedFragment {
public void onClick(View v) {
final Intent intent = new Intent(getActivity(), StorageWizardFormatProgress.class);
intent.putExtra(DiskInfo.EXTRA_DISK_ID, mDisk.getId());
- intent.putExtra(StorageWizardFormatProgress.EXTRA_FORMAT_PUBLIC, true);
+ intent.putExtra(StorageWizardFormatConfirm.EXTRA_FORMAT_PRIVATE, false);
startActivity(intent);
getActivity().finish();
}
diff --git a/src/com/android/settings/deviceinfo/PrivateVolumeSettings.java b/src/com/android/settings/deviceinfo/PrivateVolumeSettings.java
index 492051dc7..3e2b5704f 100644
--- a/src/com/android/settings/deviceinfo/PrivateVolumeSettings.java
+++ b/src/com/android/settings/deviceinfo/PrivateVolumeSettings.java
@@ -37,10 +37,10 @@ import android.os.UserManager;
import android.os.storage.StorageEventListener;
import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo;
+import android.os.storage.VolumeRecord;
import android.preference.Preference;
import android.preference.PreferenceScreen;
import android.provider.MediaStore;
-import android.text.TextUtils;
import android.text.format.Formatter;
import android.util.Log;
import android.view.LayoutInflater;
@@ -160,7 +160,7 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment {
setHasOptionsMenu(true);
}
- public void refresh() {
+ public void update() {
getActivity().setTitle(mStorageManager.getBestVolumeDescription(mVolume));
// Valid options may have changed
@@ -245,7 +245,7 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment {
}
mStorageManager.registerListener(mStorageListener);
- refresh();
+ update();
}
@Override
@@ -297,19 +297,19 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment {
final Bundle args = new Bundle();
switch (item.getItemId()) {
case R.id.storage_rename:
- RenameFragment.show(this);
+ RenameFragment.show(this, mVolume);
return true;
case R.id.storage_mount:
new MountTask(context, mVolume).execute();
return true;
case R.id.storage_unmount:
args.putString(VolumeInfo.EXTRA_VOLUME_ID, mVolume.getId());
- startFragment(this, PrivateVolumeUnmountConfirm.class.getCanonicalName(),
+ startFragment(this, PrivateVolumeUnmount.class.getCanonicalName(),
R.string.storage_menu_unmount, 0, args);
return true;
case R.id.storage_format:
args.putString(VolumeInfo.EXTRA_VOLUME_ID, mVolume.getId());
- startFragment(this, PrivateVolumeFormatConfirm.class.getCanonicalName(),
+ startFragment(this, PrivateVolumeFormat.class.getCanonicalName(),
R.string.storage_menu_format, 0, args);
return true;
case R.id.storage_usb:
@@ -437,15 +437,15 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment {
public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
if (Objects.equals(mVolume.getId(), vol.getId())) {
mVolume = vol;
- refresh();
+ update();
}
}
@Override
- public void onVolumeMetadataChanged(VolumeInfo vol) {
- if (Objects.equals(mVolume.getId(), vol.getId())) {
- mVolume = vol;
- refresh();
+ public void onVolumeMetadataChanged(String fsUuid) {
+ if (Objects.equals(mVolume.getFsUuid(), fsUuid)) {
+ mVolume = mStorageManager.findVolumeById(mVolumeId);
+ update();
}
}
};
@@ -454,12 +454,14 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment {
* Dialog that allows editing of volume nickname.
*/
public static class RenameFragment extends DialogFragment {
- public static void show(PrivateVolumeSettings parent) {
+ public static void show(PrivateVolumeSettings parent, VolumeInfo vol) {
if (!parent.isAdded()) return;
final RenameFragment dialog = new RenameFragment();
dialog.setTargetFragment(parent, 0);
- dialog.setArguments(parent.getArguments());
+ final Bundle args = new Bundle();
+ args.putString(VolumeRecord.EXTRA_FS_UUID, vol.getFsUuid());
+ dialog.setArguments(args);
dialog.show(parent.getFragmentManager(), TAG_RENAME);
}
@@ -468,20 +470,16 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment {
final Context context = getActivity();
final StorageManager storageManager = context.getSystemService(StorageManager.class);
- final String volId = getArguments().getString(VolumeInfo.EXTRA_VOLUME_ID);
- final VolumeInfo vol = storageManager.findVolumeById(volId);
+ final String fsUuid = getArguments().getString(VolumeRecord.EXTRA_FS_UUID);
+ final VolumeInfo vol = storageManager.findVolumeByUuid(fsUuid);
+ final VolumeRecord rec = storageManager.findRecordByUuid(fsUuid);
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
final LayoutInflater dialogInflater = LayoutInflater.from(builder.getContext());
final View view = dialogInflater.inflate(R.layout.dialog_edittext, null, false);
final EditText nickname = (EditText) view.findViewById(R.id.edittext);
-
- if (!TextUtils.isEmpty(vol.getNickname())) {
- nickname.setText(vol.getNickname());
- } else {
- nickname.setText(storageManager.getBestVolumeDescription(vol));
- }
+ nickname.setText(rec.getNickname());
builder.setTitle(R.string.storage_rename_title);
builder.setView(view);
@@ -491,7 +489,8 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO: move to background thread
- storageManager.setVolumeNickname(volId, nickname.getText().toString());
+ storageManager.setVolumeNickname(fsUuid,
+ nickname.getText().toString());
}
});
builder.setNegativeButton(R.string.cancel, null);
@@ -552,7 +551,7 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment {
public void onRemoveCompleted(final String packageName, final boolean succeeded) {
synchronized (this) {
if (--mRemaining == 0) {
- mTarget.refresh();
+ mTarget.update();
}
}
}
diff --git a/src/com/android/settings/deviceinfo/PrivateVolumeUnmountConfirm.java b/src/com/android/settings/deviceinfo/PrivateVolumeUnmount.java
index 614b73764..410db8fca 100644
--- a/src/com/android/settings/deviceinfo/PrivateVolumeUnmountConfirm.java
+++ b/src/com/android/settings/deviceinfo/PrivateVolumeUnmount.java
@@ -33,7 +33,7 @@ import com.android.settings.InstrumentedFragment;
import com.android.settings.R;
import com.android.settings.deviceinfo.StorageSettings.UnmountTask;
-public class PrivateVolumeUnmountConfirm extends InstrumentedFragment {
+public class PrivateVolumeUnmount extends InstrumentedFragment {
private VolumeInfo mVolume;
private DiskInfo mDisk;
diff --git a/src/com/android/settings/deviceinfo/PublicVolumeSettings.java b/src/com/android/settings/deviceinfo/PublicVolumeSettings.java
index e0b684327..1d7991dfa 100644
--- a/src/com/android/settings/deviceinfo/PublicVolumeSettings.java
+++ b/src/com/android/settings/deviceinfo/PublicVolumeSettings.java
@@ -33,7 +33,6 @@ import com.android.internal.logging.MetricsLogger;
import com.android.internal.util.Preconditions;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.deviceinfo.StorageSettings.FormatTask;
import com.android.settings.deviceinfo.StorageSettings.MountTask;
import com.android.settings.deviceinfo.StorageSettings.UnmountTask;
@@ -110,7 +109,7 @@ public class PublicVolumeSettings extends SettingsPreferenceFragment {
mFormatInternal = buildAction(R.string.storage_menu_format_internal);
}
- public void refresh() {
+ public void update() {
getActivity().setTitle(mStorageManager.getBestVolumeDescription(mVolume));
final Context context = getActivity();
@@ -180,7 +179,7 @@ public class PublicVolumeSettings extends SettingsPreferenceFragment {
}
mStorageManager.registerListener(mStorageListener);
- refresh();
+ update();
}
@Override
@@ -197,10 +196,14 @@ public class PublicVolumeSettings extends SettingsPreferenceFragment {
} else if (pref == mUnmount) {
new UnmountTask(context, mVolume).execute();
} else if (pref == mFormat) {
- new FormatTask(context, mVolume).execute();
+ final Intent intent = new Intent(context, StorageWizardFormatConfirm.class);
+ intent.putExtra(DiskInfo.EXTRA_DISK_ID, mDisk.getId());
+ intent.putExtra(StorageWizardFormatConfirm.EXTRA_FORMAT_PRIVATE, false);
+ startActivity(intent);
} else if (pref == mFormatInternal) {
final Intent intent = new Intent(context, StorageWizardFormatConfirm.class);
intent.putExtra(DiskInfo.EXTRA_DISK_ID, mDisk.getId());
+ intent.putExtra(StorageWizardFormatConfirm.EXTRA_FORMAT_PRIVATE, true);
startActivity(intent);
}
@@ -212,15 +215,15 @@ public class PublicVolumeSettings extends SettingsPreferenceFragment {
public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
if (Objects.equals(mVolume.getId(), vol.getId())) {
mVolume = vol;
- refresh();
+ update();
}
}
@Override
- public void onVolumeMetadataChanged(VolumeInfo vol) {
- if (Objects.equals(mVolume.getId(), vol.getId())) {
- mVolume = vol;
- refresh();
+ public void onVolumeMetadataChanged(String fsUuid) {
+ if (Objects.equals(mVolume.getFsUuid(), fsUuid)) {
+ mVolume = mStorageManager.findVolumeById(mVolumeId);
+ update();
}
}
};
diff --git a/src/com/android/settings/deviceinfo/StorageSettings.java b/src/com/android/settings/deviceinfo/StorageSettings.java
index 7a7d90d63..4c03d8f99 100644
--- a/src/com/android/settings/deviceinfo/StorageSettings.java
+++ b/src/com/android/settings/deviceinfo/StorageSettings.java
@@ -273,43 +273,6 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index
}
}
- public static class FormatTask extends AsyncTask<Void, Void, Exception> {
- private final Context mContext;
- private final StorageManager mStorageManager;
- private final String mVolumeId;
- private final String mDescription;
-
- public FormatTask(Context context, VolumeInfo volume) {
- mContext = context.getApplicationContext();
- mStorageManager = mContext.getSystemService(StorageManager.class);
- mVolumeId = volume.getId();
- mDescription = mStorageManager.getBestVolumeDescription(volume);
- }
-
- @Override
- protected Exception doInBackground(Void... params) {
- try {
- mStorageManager.format(mVolumeId);
- mStorageManager.mount(mVolumeId);
- return null;
- } catch (Exception e) {
- return e;
- }
- }
-
- @Override
- protected void onPostExecute(Exception e) {
- if (e == null) {
- Toast.makeText(mContext, mContext.getString(R.string.storage_format_success,
- mDescription), Toast.LENGTH_SHORT).show();
- } else {
- Log.e(TAG, "Failed to format " + mVolumeId, e);
- Toast.makeText(mContext, mContext.getString(R.string.storage_format_failure,
- mDescription), Toast.LENGTH_SHORT).show();
- }
- }
- }
-
/**
* Enable indexing of searchable data
*/
diff --git a/src/com/android/settings/deviceinfo/StorageWizardFormatConfirm.java b/src/com/android/settings/deviceinfo/StorageWizardFormatConfirm.java
index f4f475f5e..81073d671 100644
--- a/src/com/android/settings/deviceinfo/StorageWizardFormatConfirm.java
+++ b/src/com/android/settings/deviceinfo/StorageWizardFormatConfirm.java
@@ -24,6 +24,10 @@ import com.android.internal.util.Preconditions;
import com.android.settings.R;
public class StorageWizardFormatConfirm extends StorageWizardBase {
+ public static final String EXTRA_FORMAT_PRIVATE = "format_private";
+
+ private boolean mFormatPrivate;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -31,9 +35,17 @@ public class StorageWizardFormatConfirm extends StorageWizardBase {
Preconditions.checkNotNull(mDisk);
- setHeaderText(R.string.storage_wizard_format_confirm_title);
- setBodyText(R.string.storage_wizard_format_confirm_body,
- mDisk.getDescription());
+ mFormatPrivate = getIntent().getBooleanExtra(EXTRA_FORMAT_PRIVATE, false);
+
+ if (mFormatPrivate) {
+ setHeaderText(R.string.storage_wizard_format_confirm_title);
+ setBodyText(R.string.storage_wizard_format_confirm_body,
+ mDisk.getDescription());
+ } else {
+ setHeaderText(R.string.storage_wizard_format_confirm_public_title);
+ setBodyText(R.string.storage_wizard_format_confirm_public_body,
+ mDisk.getDescription());
+ }
// TODO: make this a big red scary button
getNextButton().setText(R.string.storage_wizard_format_confirm_next);
@@ -43,6 +55,7 @@ public class StorageWizardFormatConfirm extends StorageWizardBase {
public void onNavigateNext() {
final Intent intent = new Intent(this, StorageWizardFormatProgress.class);
intent.putExtra(DiskInfo.EXTRA_DISK_ID, mDisk.getId());
+ intent.putExtra(EXTRA_FORMAT_PRIVATE, mFormatPrivate);
startActivity(intent);
finishAffinity();
}
diff --git a/src/com/android/settings/deviceinfo/StorageWizardFormatProgress.java b/src/com/android/settings/deviceinfo/StorageWizardFormatProgress.java
index 2996d4548..e60bbcf78 100644
--- a/src/com/android/settings/deviceinfo/StorageWizardFormatProgress.java
+++ b/src/com/android/settings/deviceinfo/StorageWizardFormatProgress.java
@@ -31,9 +31,7 @@ import com.android.internal.util.Preconditions;
import com.android.settings.R;
public class StorageWizardFormatProgress extends StorageWizardBase {
- public static final String EXTRA_FORMAT_PUBLIC = "format_private";
-
- private boolean mFormatPublic;
+ private boolean mFormatPrivate;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -42,7 +40,8 @@ public class StorageWizardFormatProgress extends StorageWizardBase {
Preconditions.checkNotNull(mDisk);
- mFormatPublic = getIntent().getBooleanExtra(EXTRA_FORMAT_PUBLIC, false);
+ mFormatPrivate = getIntent().getBooleanExtra(
+ StorageWizardFormatConfirm.EXTRA_FORMAT_PRIVATE, false);
setHeaderText(R.string.storage_wizard_format_progress_title, mDisk.getDescription());
setBodyText(R.string.storage_wizard_format_progress_body, mDisk.getDescription());
@@ -58,10 +57,10 @@ public class StorageWizardFormatProgress extends StorageWizardBase {
@Override
protected Exception doInBackground(Void... params) {
try {
- if (mFormatPublic) {
- mStorage.partitionPublic(mDisk.getId());
- } else {
+ if (mFormatPrivate) {
mStorage.partitionPrivate(mDisk.getId());
+ } else {
+ mStorage.partitionPublic(mDisk.getId());
}
return null;
} catch (Exception e) {
@@ -73,7 +72,7 @@ public class StorageWizardFormatProgress extends StorageWizardBase {
protected void onPostExecute(Exception e) {
final Context context = StorageWizardFormatProgress.this;
if (e == null) {
- if (!mFormatPublic) {
+ if (mFormatPrivate) {
// TODO: bring back migration once implemented
// final Intent intent = new Intent(context, StorageWizardMigrate.class);
// intent.putExtra(DiskInfo.EXTRA_DISK_ID, mDisk.getId());
@@ -81,6 +80,10 @@ public class StorageWizardFormatProgress extends StorageWizardBase {
final Intent intent = new Intent(context, StorageWizardReady.class);
intent.putExtra(DiskInfo.EXTRA_DISK_ID, mDisk.getId());
startActivity(intent);
+ } else {
+ final Intent intent = new Intent(context, StorageWizardReady.class);
+ intent.putExtra(DiskInfo.EXTRA_DISK_ID, mDisk.getId());
+ startActivity(intent);
}
finishAffinity();
diff --git a/src/com/android/settings/deviceinfo/StorageWizardInit.java b/src/com/android/settings/deviceinfo/StorageWizardInit.java
index 9d59231e7..22a8008e5 100644
--- a/src/com/android/settings/deviceinfo/StorageWizardInit.java
+++ b/src/com/android/settings/deviceinfo/StorageWizardInit.java
@@ -19,6 +19,7 @@ package com.android.settings.deviceinfo;
import android.content.Intent;
import android.os.Bundle;
import android.os.storage.DiskInfo;
+import android.os.storage.VolumeInfo;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.RadioButton;
@@ -72,15 +73,26 @@ public class StorageWizardInit extends StorageWizardBase {
@Override
public void onNavigateNext() {
if (mRadioExternal.isChecked()) {
- // Remember that user made decision
- mStorage.setVolumeInited(mVolume.getId(), true);
+ if (mVolume != null && mVolume.getType() == VolumeInfo.TYPE_PUBLIC) {
+ // Remember that user made decision
+ mStorage.setVolumeInited(mVolume.getFsUuid(), true);
+
+ final Intent intent = new Intent(this, StorageWizardReady.class);
+ intent.putExtra(DiskInfo.EXTRA_DISK_ID, mDisk.getId());
+ startActivity(intent);
+
+ } else {
+ // Gotta format to get there
+ final Intent intent = new Intent(this, StorageWizardFormatConfirm.class);
+ intent.putExtra(DiskInfo.EXTRA_DISK_ID, mDisk.getId());
+ intent.putExtra(StorageWizardFormatConfirm.EXTRA_FORMAT_PRIVATE, false);
+ startActivity(intent);
+ }
- final Intent intent = new Intent(this, StorageWizardReady.class);
- intent.putExtra(DiskInfo.EXTRA_DISK_ID, mDisk.getId());
- startActivity(intent);
} else if (mRadioInternal.isChecked()) {
final Intent intent = new Intent(this, StorageWizardFormatConfirm.class);
intent.putExtra(DiskInfo.EXTRA_DISK_ID, mDisk.getId());
+ intent.putExtra(StorageWizardFormatConfirm.EXTRA_FORMAT_PRIVATE, true);
startActivity(intent);
}
}
diff --git a/src/com/android/settings/deviceinfo/StorageWizardMoveProgress.java b/src/com/android/settings/deviceinfo/StorageWizardMoveProgress.java
index b0946c566..1202b9e8b 100644
--- a/src/com/android/settings/deviceinfo/StorageWizardMoveProgress.java
+++ b/src/com/android/settings/deviceinfo/StorageWizardMoveProgress.java
@@ -49,7 +49,7 @@ public class StorageWizardMoveProgress extends StorageWizardBase {
// Register for updates and push through current status
getPackageManager().registerMoveCallback(mCallback, new Handler());
- mCallback.onStatusChanged(mMoveId, getPackageManager().getMoveStatus(mMoveId), -1);
+ mCallback.onStatusChanged(mMoveId, null, getPackageManager().getMoveStatus(mMoveId), -1);
}
@Override
@@ -60,12 +60,7 @@ public class StorageWizardMoveProgress extends StorageWizardBase {
private final MoveCallback mCallback = new MoveCallback() {
@Override
- public void onStarted(int moveId, String title) {
- // Ignored
- }
-
- @Override
- public void onStatusChanged(int moveId, int status, long estMillis) {
+ public void onStatusChanged(int moveId, String moveTitle, int status, long estMillis) {
if (mMoveId != moveId) return;
if (PackageManager.isMoveStatusFinished(status)) {
diff --git a/src/com/android/settings/fingerprint/FingerprintEnrollEnrolling.java b/src/com/android/settings/fingerprint/FingerprintEnrollEnrolling.java
index e70c4054f..6d0d10bf7 100644
--- a/src/com/android/settings/fingerprint/FingerprintEnrollEnrolling.java
+++ b/src/com/android/settings/fingerprint/FingerprintEnrollEnrolling.java
@@ -17,17 +17,15 @@
package com.android.settings.fingerprint;
import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.content.Intent;
-import android.hardware.fingerprint.FingerprintManager;
+import android.graphics.drawable.AnimatedVectorDrawable;
import android.os.Bundle;
-import android.os.CancellationSignal;
-import android.os.PowerManager;
-import android.os.SystemClock;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.AnimationUtils;
@@ -51,6 +49,11 @@ public class FingerprintEnrollEnrolling extends FingerprintEnrollBase
private static final int FINISH_DELAY = 250;
/**
+ * How long the user needs to touch the icon until we show the dialog.
+ */
+ private static final long ICON_TOUCH_DURATION_UNTIL_DIALOG_SHOWN = 500;
+
+ /**
* How many times the user needs to touch the icon until we show the dialog that this is not the
* fingerprint sensor.
*/
@@ -65,6 +68,8 @@ public class FingerprintEnrollEnrolling extends FingerprintEnrollBase
private Interpolator mFastOutSlowInInterpolator;
private int mIconTouchCount;
private FingerprintEnrollSidecar mSidecar;
+ private boolean mAnimationCancelled;
+ private AnimatedVectorDrawable mIconAnimationDrawable;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -76,17 +81,24 @@ public class FingerprintEnrollEnrolling extends FingerprintEnrollBase
mErrorText = (TextView) findViewById(R.id.error_text);
mProgressBar = (ProgressBar) findViewById(R.id.fingerprint_progress_bar);
mFingerprintAnimator = (ImageView) findViewById(R.id.fingerprint_animator);
+ mIconAnimationDrawable = (AnimatedVectorDrawable) mFingerprintAnimator.getDrawable();
+ mIconAnimationDrawable.addListener(mIconAnimationListener);
mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(
this, android.R.interpolator.fast_out_slow_in);
- findViewById(R.id.fingerprint_animator).setOnTouchListener(new View.OnTouchListener() {
+ mFingerprintAnimator.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
mIconTouchCount++;
if (mIconTouchCount == ICON_TOUCH_COUNT_SHOW_UNTIL_DIALOG_SHOWN) {
showIconTouchDialog();
- mIconTouchCount = 0;
+ } else {
+ mFingerprintAnimator.postDelayed(mShowDialogRunnable,
+ ICON_TOUCH_DURATION_UNTIL_DIALOG_SHOWN);
}
+ } else if (event.getActionMasked() == MotionEvent.ACTION_CANCEL
+ || event.getActionMasked() == MotionEvent.ACTION_UP) {
+ mFingerprintAnimator.removeCallbacks(mShowDialogRunnable);
}
return true;
}
@@ -102,18 +114,31 @@ public class FingerprintEnrollEnrolling extends FingerprintEnrollBase
getFragmentManager().beginTransaction().add(mSidecar, TAG_SIDECAR).commit();
}
mSidecar.setListener(this);
- if (mSidecar.isDone()) {
- launchFinish(mToken);
- } else {
- updateProgress(false /* animate */);
- updateDescription();
- }
+ updateProgress(false /* animate */);
+ updateDescription();
+ }
+
+ @Override
+ public void onEnterAnimationComplete() {
+ super.onEnterAnimationComplete();
+ mAnimationCancelled = false;
+ startIconAnimation();
+ }
+
+ private void startIconAnimation() {
+ mIconAnimationDrawable.start();
+ }
+
+ private void stopIconAnimation() {
+ mAnimationCancelled = true;
+ mIconAnimationDrawable.stop();
}
@Override
protected void onStop() {
super.onStop();
mSidecar.setListener(null);
+ stopIconAnimation();
}
private void animateProgress(int progress) {
@@ -187,6 +212,7 @@ public class FingerprintEnrollEnrolling extends FingerprintEnrollBase
}
private void showIconTouchDialog() {
+ mIconTouchCount = 0;
new IconTouchDialog().show(getFragmentManager(), null /* tag */);
}
@@ -211,13 +237,37 @@ public class FingerprintEnrollEnrolling extends FingerprintEnrollBase
};
// Give the user a chance to see progress completed before jumping to the next stage.
- Runnable mDelayedFinishRunnable = new Runnable() {
+ private final Runnable mDelayedFinishRunnable = new Runnable() {
@Override
public void run() {
launchFinish(mToken);
}
};
+ private final Animator.AnimatorListener mIconAnimationListener = new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (mAnimationCancelled) {
+ return;
+ }
+
+ // Start animation after it has ended.
+ mFingerprintAnimator.post(new Runnable() {
+ @Override
+ public void run() {
+ startIconAnimation();
+ }
+ });
+ }
+ };
+
+ private final Runnable mShowDialogRunnable = new Runnable() {
+ @Override
+ public void run() {
+ showIconTouchDialog();
+ }
+ };
+
private static class IconTouchDialog extends DialogFragment {
@Override
diff --git a/src/com/android/settings/notification/AppNotificationSettings.java b/src/com/android/settings/notification/AppNotificationSettings.java
index 129c35955..883975a5a 100644
--- a/src/com/android/settings/notification/AppNotificationSettings.java
+++ b/src/com/android/settings/notification/AppNotificationSettings.java
@@ -26,6 +26,7 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
+import android.os.UserHandle;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.SwitchPreference;
@@ -191,7 +192,8 @@ public class AppNotificationSettings extends SettingsPreferenceFragment {
}
private void updateDependents(boolean banned) {
- final boolean lockscreenSecure = new LockPatternUtils(getActivity()).isSecure();
+ final boolean lockscreenSecure = new LockPatternUtils(getActivity()).isSecure(
+ UserHandle.myUserId());
final boolean lockscreenNotificationsEnabled = getLockscreenNotificationsEnabled();
final boolean allowPrivate = getLockscreenAllowPrivateNotifications();
diff --git a/src/com/android/settings/notification/NotificationSettings.java b/src/com/android/settings/notification/NotificationSettings.java
index 581b7078b..cdff32f26 100644
--- a/src/com/android/settings/notification/NotificationSettings.java
+++ b/src/com/android/settings/notification/NotificationSettings.java
@@ -36,6 +36,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
+import android.os.UserHandle;
import android.os.Vibrator;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
@@ -116,7 +117,7 @@ public class NotificationSettings extends SettingsPreferenceFragment implements
mContext = getActivity();
mPM = mContext.getPackageManager();
mVoiceCapable = Utils.isVoiceCapable(mContext);
- mSecure = new LockPatternUtils(getActivity()).isSecure();
+ mSecure = new LockPatternUtils(getActivity()).isSecure(UserHandle.myUserId());
mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
mVibrator = (Vibrator) getActivity().getSystemService(Context.VIBRATOR_SERVICE);
diff --git a/src/com/android/settings/users/UserDialogs.java b/src/com/android/settings/users/UserDialogs.java
index 2d92464ac..23012b3f3 100644
--- a/src/com/android/settings/users/UserDialogs.java
+++ b/src/com/android/settings/users/UserDialogs.java
@@ -20,11 +20,19 @@ import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
+import android.graphics.drawable.Drawable;
import android.os.UserHandle;
import android.os.UserManager;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
import com.android.settings.R;
+import com.android.settings.Utils;
/**
* Helper class for displaying dialogs related to user settings.
@@ -44,27 +52,60 @@ public final class UserDialogs {
DialogInterface.OnClickListener onConfirmListener) {
UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
UserInfo userInfo = um.getUserInfo(removingUserId);
- int titleResId;
- int messageResId;
+ AlertDialog.Builder builder = new AlertDialog.Builder(context)
+ .setPositiveButton(R.string.user_delete_button, onConfirmListener)
+ .setNegativeButton(android.R.string.cancel, null);
if (UserHandle.myUserId() == removingUserId) {
- titleResId = R.string.user_confirm_remove_self_title;
- messageResId = R.string.user_confirm_remove_self_message;
+ builder.setTitle(R.string.user_confirm_remove_self_title);
+ builder.setMessage(R.string.user_confirm_remove_self_message);
} else if (userInfo.isRestricted()) {
- titleResId = R.string.user_profile_confirm_remove_title;
- messageResId = R.string.user_profile_confirm_remove_message;
+ builder.setTitle(R.string.user_profile_confirm_remove_title);
+ builder.setMessage(R.string.user_profile_confirm_remove_message);
} else if (userInfo.isManagedProfile()) {
- titleResId = R.string.work_profile_confirm_remove_title;
- messageResId = R.string.work_profile_confirm_remove_message;
+ builder.setTitle(R.string.work_profile_confirm_remove_title);
+ View view = createRemoveManagedUserDialogView(context, removingUserId);
+ if (view != null) {
+ builder.setView(view);
+ } else {
+ builder.setMessage(R.string.work_profile_confirm_remove_message);
+ }
} else {
- titleResId = R.string.user_confirm_remove_title;
- messageResId = R.string.user_confirm_remove_message;
+ builder.setTitle(R.string.user_confirm_remove_title);
+ builder.setMessage(R.string.user_confirm_remove_message);
}
- return new AlertDialog.Builder(context)
- .setTitle(titleResId)
- .setMessage(messageResId)
- .setPositiveButton(R.string.user_delete_button, onConfirmListener)
- .setNegativeButton(android.R.string.cancel, null)
- .create();
+ return builder.create();
+ }
+
+ /**
+ * Creates a view to be used in the confirmation dialog for removing work profile.
+ */
+ private static View createRemoveManagedUserDialogView(Context context, int userId) {
+ PackageManager packageManager = context.getPackageManager();
+ ApplicationInfo mdmApplicationInfo = Utils.getAdminApplicationInfo(context, userId);
+ if (mdmApplicationInfo == null) {
+ return null;
+ }
+ LayoutInflater inflater =
+ (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+
+ View view = inflater.inflate(R.layout.delete_managed_profile_dialog, null);
+ ImageView imageView =
+ (ImageView) view.findViewById(R.id.delete_managed_profile_mdm_icon_view);
+ Drawable badgedApplicationIcon = packageManager.getUserBadgedIcon(
+ packageManager.getApplicationIcon(mdmApplicationInfo), new UserHandle(userId));
+ imageView.setImageDrawable(badgedApplicationIcon);
+
+ CharSequence appLabel = packageManager.getApplicationLabel(mdmApplicationInfo);
+ CharSequence badgedAppLabel = packageManager.getUserBadgedLabel(appLabel,
+ new UserHandle(userId));
+ TextView textView =
+ (TextView) view.findViewById(R.id.delete_managed_profile_device_manager_name);
+ textView.setText(appLabel);
+ if (!appLabel.toString().contentEquals(badgedAppLabel)) {
+ textView.setContentDescription(badgedAppLabel);
+ }
+
+ return view;
}
/**
diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java
index f3b60fc99..cef083335 100644
--- a/src/com/android/settings/users/UserSettings.java
+++ b/src/com/android/settings/users/UserSettings.java
@@ -357,7 +357,7 @@ public class UserSettings extends SettingsPreferenceFragment
private boolean hasLockscreenSecurity() {
LockPatternUtils lpu = new LockPatternUtils(getActivity());
- return lpu.isLockPasswordEnabled() || lpu.isLockPatternEnabled();
+ return lpu.isSecure(UserHandle.myUserId());
}
private void launchChooseLockscreen() {