Animations/success state for external confirm device credentials (2/2)
Bug: 20929186 Change-Id: I4489dd37f1148fb03315ec337a546eee04660cb5
This commit is contained in:
@@ -1407,7 +1407,7 @@
|
|||||||
android:theme="@style/Theme.ConfirmDeviceCredentials"/>
|
android:theme="@style/Theme.ConfirmDeviceCredentials"/>
|
||||||
|
|
||||||
<activity android:name="ConfirmLockPassword"
|
<activity android:name="ConfirmLockPassword"
|
||||||
android:windowSoftInputMode="adjustResize"
|
android:windowSoftInputMode="stateHidden|adjustResize"
|
||||||
android:theme="@style/Theme.ConfirmDeviceCredentials"/>
|
android:theme="@style/Theme.ConfirmDeviceCredentials"/>
|
||||||
|
|
||||||
<activity android:name=".fingerprint.FingerprintSettings" android:exported="false"/>
|
<activity android:name=".fingerprint.FingerprintSettings" android:exported="false"/>
|
||||||
|
30
res/anim/confirm_credential_close_enter.xml
Normal file
30
res/anim/confirm_credential_close_enter.xml
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
<?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"
|
||||||
|
android:shareInterpolator="false"
|
||||||
|
android:zAdjustment="top">
|
||||||
|
<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
|
||||||
|
android:interpolator="@*android:interpolator/decelerate_quart"
|
||||||
|
android:fillEnabled="true"
|
||||||
|
android:fillBefore="false" android:fillAfter="true"
|
||||||
|
android:duration="200"/>
|
||||||
|
<translate android:fromYDelta="8%" android:toYDelta="0"
|
||||||
|
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
|
||||||
|
android:interpolator="@*android:interpolator/decelerate_quint"
|
||||||
|
android:duration="350"/>
|
||||||
|
</set>
|
21
res/anim/confirm_credential_close_exit.xml
Normal file
21
res/anim/confirm_credential_close_exit.xml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?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
|
||||||
|
-->
|
||||||
|
|
||||||
|
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:interpolator="@android:interpolator/linear_out_slow_in"
|
||||||
|
android:fromAlpha="1.0" android:toAlpha="0.0"
|
||||||
|
android:duration="350" />
|
21
res/anim/confirm_credential_open_enter.xml
Normal file
21
res/anim/confirm_credential_open_enter.xml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?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
|
||||||
|
-->
|
||||||
|
|
||||||
|
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:interpolator="@android:interpolator/linear_out_slow_in"
|
||||||
|
android:fromAlpha="0.0" android:toAlpha="1.0"
|
||||||
|
android:duration="160" />
|
20
res/anim/confirm_credential_open_exit.xml
Normal file
20
res/anim/confirm_credential_open_exit.xml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<?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
|
||||||
|
-->
|
||||||
|
|
||||||
|
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:fromAlpha="1.0" android:toAlpha="1.0"
|
||||||
|
android:duration="160" />
|
29
res/drawable/ic_fingerprint_success.xml
Normal file
29
res/drawable/ic_fingerprint_success.xml
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<?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:width="32.0dp"
|
||||||
|
android:height="32.0dp"
|
||||||
|
android:viewportWidth="40.0"
|
||||||
|
android:viewportHeight="40.0">
|
||||||
|
<path
|
||||||
|
android:pathData="M20.0,20.0m-20.0,0.0a20.0,20.0 0.0,1.0 1.0,40.0 0.0a20.0,20.0 0.0,1.0 1.0,-40.0 0.0"
|
||||||
|
android:fillColor="?android:attr/colorAccent"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M11.2,21.41l1.63,-1.619999 4.17,4.169998 10.59,-10.589999 1.619999,1.63 -12.209999,12.209999z"
|
||||||
|
android:fillColor="#FFFFFF"/>
|
||||||
|
</vector>
|
@@ -225,6 +225,11 @@
|
|||||||
<item name="android:layout_height">wrap_content</item>
|
<item name="android:layout_height">wrap_content</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style name="ConfirmDeviceCredentialsAnimationStyle" parent="@*android:style/Animation.Material.Activity">
|
||||||
|
<item name="android:activityOpenEnterAnimation">@anim/confirm_credential_open_enter</item>
|
||||||
|
<item name="android:activityOpenExitAnimation">@anim/confirm_credential_open_exit</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
<style name="Transparent">
|
<style name="Transparent">
|
||||||
<item name="android:windowBackground">@android:color/transparent</item>
|
<item name="android:windowBackground">@android:color/transparent</item>
|
||||||
<item name="android:windowNoTitle">true</item>
|
<item name="android:windowNoTitle">true</item>
|
||||||
|
@@ -199,7 +199,7 @@
|
|||||||
<item name="android:colorPrimaryDark">@*android:color/material_blue_grey_950</item>
|
<item name="android:colorPrimaryDark">@*android:color/material_blue_grey_950</item>
|
||||||
<item name="android:windowActionBar">false</item>
|
<item name="android:windowActionBar">false</item>
|
||||||
<item name="android:windowNoTitle">true</item>
|
<item name="android:windowNoTitle">true</item>
|
||||||
<item name="preferenceBackgroundColor">@color/confirm_device_credential_dark_background</item>
|
<item name="android:windowBackground">@color/confirm_device_credential_dark_background</item>
|
||||||
|
|
||||||
<item name="confirmDeviceCredentialsSideMargin">32dp</item>
|
<item name="confirmDeviceCredentialsSideMargin">32dp</item>
|
||||||
<item name="confirmDeviceCredentialsTopMargin">32dp</item>
|
<item name="confirmDeviceCredentialsTopMargin">32dp</item>
|
||||||
@@ -208,6 +208,8 @@
|
|||||||
<item name="@*android:regularColor">@color/lock_pattern_view_regular_color_dark</item>
|
<item name="@*android:regularColor">@color/lock_pattern_view_regular_color_dark</item>
|
||||||
<item name="@*android:successColor">@color/lock_pattern_view_regular_color_dark</item>
|
<item name="@*android:successColor">@color/lock_pattern_view_regular_color_dark</item>
|
||||||
<item name="@*android:errorColor">@color/lock_pattern_view_error_color</item>
|
<item name="@*android:errorColor">@color/lock_pattern_view_error_color</item>
|
||||||
|
|
||||||
|
<item name="android:windowAnimationStyle">@style/ConfirmDeviceCredentialsAnimationStyle</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="Theme.FingerprintEnroll" parent="@*android:style/Theme.Material.Settings.NoActionBar">
|
<style name="Theme.FingerprintEnroll" parent="@*android:style/Theme.Material.Settings.NoActionBar">
|
||||||
|
@@ -16,17 +16,23 @@
|
|||||||
|
|
||||||
package com.android.settings;
|
package com.android.settings;
|
||||||
|
|
||||||
|
import android.app.Fragment;
|
||||||
import android.app.KeyguardManager;
|
import android.app.KeyguardManager;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
|
|
||||||
public class ConfirmDeviceCredentialBaseActivity extends SettingsActivity {
|
public abstract class ConfirmDeviceCredentialBaseActivity extends SettingsActivity {
|
||||||
|
|
||||||
|
private boolean mRestoring;
|
||||||
|
private boolean mDark;
|
||||||
|
private boolean mEnterAnimationPending;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedState) {
|
protected void onCreate(Bundle savedState) {
|
||||||
if (getIntent().getBooleanExtra(ConfirmDeviceCredentialBaseFragment.DARK_THEME, false)) {
|
if (getIntent().getBooleanExtra(ConfirmDeviceCredentialBaseFragment.DARK_THEME, false)) {
|
||||||
setTheme(R.style.Theme_ConfirmDeviceCredentialsDark);
|
setTheme(R.style.Theme_ConfirmDeviceCredentialsDark);
|
||||||
|
mDark = true;
|
||||||
}
|
}
|
||||||
super.onCreate(savedState);
|
super.onCreate(savedState);
|
||||||
boolean deviceLocked = getSystemService(KeyguardManager.class).isKeyguardLocked();
|
boolean deviceLocked = getSystemService(KeyguardManager.class).isKeyguardLocked();
|
||||||
@@ -41,6 +47,7 @@ public class ConfirmDeviceCredentialBaseActivity extends SettingsActivity {
|
|||||||
getActionBar().setDisplayHomeAsUpEnabled(true);
|
getActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
getActionBar().setHomeButtonEnabled(true);
|
getActionBar().setHomeButtonEnabled(true);
|
||||||
}
|
}
|
||||||
|
mRestoring = savedState != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -51,4 +58,37 @@ public class ConfirmDeviceCredentialBaseActivity extends SettingsActivity {
|
|||||||
}
|
}
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
if (!isChangingConfigurations() && !mRestoring && mDark) {
|
||||||
|
prepareEnterAnimation();
|
||||||
|
mEnterAnimationPending = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ConfirmDeviceCredentialBaseFragment getFragment() {
|
||||||
|
Fragment fragment = getFragmentManager().findFragmentById(R.id.main_content);
|
||||||
|
if (fragment != null && fragment instanceof ConfirmDeviceCredentialBaseFragment) {
|
||||||
|
return (ConfirmDeviceCredentialBaseFragment) fragment;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnterAnimationComplete() {
|
||||||
|
super.onEnterAnimationComplete();
|
||||||
|
if (mEnterAnimationPending) {
|
||||||
|
startEnterAnimation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void prepareEnterAnimation() {
|
||||||
|
getFragment().prepareEnterAnimation();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startEnterAnimation() {
|
||||||
|
getFragment().startEnterAnimation();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -45,6 +45,8 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFr
|
|||||||
|
|
||||||
private FingerprintUiHelper mFingerprintHelper;
|
private FingerprintUiHelper mFingerprintHelper;
|
||||||
private boolean mAllowFpAuthentication;
|
private boolean mAllowFpAuthentication;
|
||||||
|
protected Button mCancelButton;
|
||||||
|
protected ImageView mFingerprintIcon;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
@@ -56,14 +58,15 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFr
|
|||||||
@Override
|
@Override
|
||||||
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
||||||
super.onViewCreated(view, savedInstanceState);
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
mCancelButton = (Button) view.findViewById(R.id.cancelButton);
|
||||||
|
mFingerprintIcon = (ImageView) view.findViewById(R.id.fingerprintIcon);
|
||||||
mFingerprintHelper = new FingerprintUiHelper(
|
mFingerprintHelper = new FingerprintUiHelper(
|
||||||
(ImageView) view.findViewById(R.id.fingerprintIcon),
|
mFingerprintIcon,
|
||||||
(TextView) view.findViewById(R.id.errorText), this);
|
(TextView) view.findViewById(R.id.errorText), this);
|
||||||
boolean showCancelButton = getActivity().getIntent().getBooleanExtra(
|
boolean showCancelButton = getActivity().getIntent().getBooleanExtra(
|
||||||
SHOW_CANCEL_BUTTON, false);
|
SHOW_CANCEL_BUTTON, false);
|
||||||
Button cancelButton = (Button) view.findViewById(R.id.cancelButton);
|
mCancelButton.setVisibility(showCancelButton ? View.VISIBLE : View.GONE);
|
||||||
cancelButton.setVisibility(showCancelButton ? View.VISIBLE : View.GONE);
|
mCancelButton.setOnClickListener(new View.OnClickListener() {
|
||||||
cancelButton.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
getActivity().finish();
|
getActivity().finish();
|
||||||
@@ -100,4 +103,10 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFr
|
|||||||
@Override
|
@Override
|
||||||
public void onFingerprintIconVisibilityChanged(boolean visible) {
|
public void onFingerprintIconVisibilityChanged(boolean visible) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void prepareEnterAnimation() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startEnterAnimation() {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -19,9 +19,12 @@ package com.android.settings;
|
|||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import com.android.internal.logging.MetricsLogger;
|
import com.android.internal.logging.MetricsLogger;
|
||||||
|
import com.android.internal.util.ArrayUtils;
|
||||||
import com.android.internal.widget.LockPatternChecker;
|
import com.android.internal.widget.LockPatternChecker;
|
||||||
import com.android.internal.widget.LockPatternUtils;
|
import com.android.internal.widget.LockPatternUtils;
|
||||||
import com.android.internal.widget.TextViewInputDisabler;
|
import com.android.internal.widget.TextViewInputDisabler;
|
||||||
|
import com.android.settingslib.animation.AppearAnimationUtils;
|
||||||
|
import com.android.settingslib.animation.DisappearAnimationUtils;
|
||||||
|
|
||||||
import android.app.Fragment;
|
import android.app.Fragment;
|
||||||
import android.app.admin.DevicePolicyManager;
|
import android.app.admin.DevicePolicyManager;
|
||||||
@@ -39,11 +42,14 @@ import android.view.LayoutInflater;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
import android.view.View.OnClickListener;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.view.animation.AnimationUtils;
|
||||||
import android.view.inputmethod.EditorInfo;
|
import android.view.inputmethod.EditorInfo;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.TextView.OnEditorActionListener;
|
import android.widget.TextView.OnEditorActionListener;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
||||||
|
|
||||||
public static class InternalActivity extends ConfirmLockPassword {
|
public static class InternalActivity extends ConfirmLockPassword {
|
||||||
@@ -89,6 +95,9 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
private boolean mIsAlpha;
|
private boolean mIsAlpha;
|
||||||
private InputMethodManager mImm;
|
private InputMethodManager mImm;
|
||||||
private boolean mUsingFingerprint = false;
|
private boolean mUsingFingerprint = false;
|
||||||
|
private AppearAnimationUtils mAppearAnimationUtils;
|
||||||
|
private DisappearAnimationUtils mDisappearAnimationUtils;
|
||||||
|
private boolean mBlockImm;
|
||||||
|
|
||||||
// required constructor for fragments
|
// required constructor for fragments
|
||||||
public ConfirmLockPasswordFragment() {
|
public ConfirmLockPasswordFragment() {
|
||||||
@@ -144,6 +153,14 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
int currentType = mPasswordEntry.getInputType();
|
int currentType = mPasswordEntry.getInputType();
|
||||||
mPasswordEntry.setInputType(mIsAlpha ? currentType
|
mPasswordEntry.setInputType(mIsAlpha ? currentType
|
||||||
: (InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_VARIATION_PASSWORD));
|
: (InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_VARIATION_PASSWORD));
|
||||||
|
mAppearAnimationUtils = new AppearAnimationUtils(getContext(),
|
||||||
|
220, 2f /* translationScale */, 1f /* delayScale*/,
|
||||||
|
AnimationUtils.loadInterpolator(getContext(),
|
||||||
|
android.R.interpolator.linear_out_slow_in));
|
||||||
|
mDisappearAnimationUtils = new DisappearAnimationUtils(getContext(),
|
||||||
|
110, 1f /* translationScale */,
|
||||||
|
0.5f /* delayScale */, AnimationUtils.loadInterpolator(
|
||||||
|
getContext(), android.R.interpolator.fast_out_linear_in));
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,6 +179,43 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
: R.string.lockpassword_invalid_pin;
|
: R.string.lockpassword_invalid_pin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void prepareEnterAnimation() {
|
||||||
|
super.prepareEnterAnimation();
|
||||||
|
mHeaderTextView.setAlpha(0f);
|
||||||
|
mDetailsTextView.setAlpha(0f);
|
||||||
|
mCancelButton.setAlpha(0f);
|
||||||
|
mPasswordEntry.setAlpha(0f);
|
||||||
|
mFingerprintIcon.setAlpha(0f);
|
||||||
|
mBlockImm = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private View[] getActiveViews() {
|
||||||
|
ArrayList<View> result = new ArrayList<>();
|
||||||
|
result.add(mHeaderTextView);
|
||||||
|
result.add(mDetailsTextView);
|
||||||
|
if (mCancelButton.getVisibility() == View.VISIBLE) {
|
||||||
|
result.add(mCancelButton);
|
||||||
|
}
|
||||||
|
result.add(mPasswordEntry);
|
||||||
|
if (mFingerprintIcon.getVisibility() == View.VISIBLE) {
|
||||||
|
result.add(mFingerprintIcon);
|
||||||
|
}
|
||||||
|
return result.toArray(new View[] {});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startEnterAnimation() {
|
||||||
|
super.startEnterAnimation();
|
||||||
|
mAppearAnimationUtils.startAnimation(getActiveViews(), new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mBlockImm = false;
|
||||||
|
resetState();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPause() {
|
public void onPause() {
|
||||||
super.onPause();
|
super.onPause();
|
||||||
@@ -199,9 +253,7 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void authenticationSucceeded() {
|
protected void authenticationSucceeded() {
|
||||||
Intent intent = new Intent();
|
startDisappearAnimation(new Intent());
|
||||||
getActivity().setResult(RESULT_OK, intent);
|
|
||||||
getActivity().finish();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -210,6 +262,7 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void resetState() {
|
private void resetState() {
|
||||||
|
if (mBlockImm) return;
|
||||||
mPasswordEntry.setEnabled(true);
|
mPasswordEntry.setEnabled(true);
|
||||||
mPasswordEntryInputDisabler.setInputEnabled(true);
|
mPasswordEntryInputDisabler.setInputEnabled(true);
|
||||||
if (shouldAutoShowSoftKeyboard()) {
|
if (shouldAutoShowSoftKeyboard()) {
|
||||||
@@ -222,7 +275,7 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void onWindowFocusChanged(boolean hasFocus) {
|
public void onWindowFocusChanged(boolean hasFocus) {
|
||||||
if (!hasFocus) {
|
if (!hasFocus || mBlockImm) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Post to let window focus logic to finish to allow soft input show/hide properly.
|
// Post to let window focus logic to finish to allow soft input show/hide properly.
|
||||||
@@ -312,11 +365,28 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void startDisappearAnimation(final Intent intent) {
|
||||||
|
if (getActivity().getThemeResId() == R.style.Theme_ConfirmDeviceCredentialsDark) {
|
||||||
|
mDisappearAnimationUtils.startAnimation(getActiveViews(), new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
getActivity().setResult(RESULT_OK, intent);
|
||||||
|
getActivity().finish();
|
||||||
|
getActivity().overridePendingTransition(
|
||||||
|
R.anim.confirm_credential_close_enter,
|
||||||
|
R.anim.confirm_credential_close_exit);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
getActivity().setResult(RESULT_OK, intent);
|
||||||
|
getActivity().finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void onPasswordChecked(boolean matched, Intent intent, int timeoutMs) {
|
private void onPasswordChecked(boolean matched, Intent intent, int timeoutMs) {
|
||||||
mPasswordEntryInputDisabler.setInputEnabled(true);
|
mPasswordEntryInputDisabler.setInputEnabled(true);
|
||||||
if (matched) {
|
if (matched) {
|
||||||
getActivity().setResult(RESULT_OK, intent);
|
startDisappearAnimation(intent);
|
||||||
getActivity().finish();
|
|
||||||
} else {
|
} else {
|
||||||
if (timeoutMs > 0) {
|
if (timeoutMs > 0) {
|
||||||
long deadline = mLockPatternUtils.setLockoutAttemptDeadline(
|
long deadline = mLockPatternUtils.setLockoutAttemptDeadline(
|
||||||
|
@@ -22,10 +22,21 @@ import com.android.internal.widget.LockPatternView;
|
|||||||
import com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient;
|
import com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient;
|
||||||
import com.android.internal.widget.LockPatternChecker;
|
import com.android.internal.widget.LockPatternChecker;
|
||||||
import com.android.internal.widget.LockPatternView.Cell;
|
import com.android.internal.widget.LockPatternView.Cell;
|
||||||
|
import com.android.settingslib.animation.AppearAnimationCreator;
|
||||||
|
import com.android.settingslib.animation.AppearAnimationUtils;
|
||||||
|
import com.android.settingslib.animation.DisappearAnimationUtils;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.AnimatorListenerAdapter;
|
||||||
|
import android.animation.ValueAnimator;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.app.Fragment;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.PorterDuff;
|
||||||
|
import android.graphics.PorterDuffColorFilter;
|
||||||
import android.os.CountDownTimer;
|
import android.os.CountDownTimer;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
@@ -33,11 +44,16 @@ import android.os.Bundle;
|
|||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.os.storage.StorageManager;
|
import android.os.storage.StorageManager;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
import android.view.animation.AnimationUtils;
|
||||||
|
import android.view.animation.Interpolator;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -70,7 +86,8 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ConfirmLockPatternFragment extends ConfirmDeviceCredentialBaseFragment {
|
public static class ConfirmLockPatternFragment extends ConfirmDeviceCredentialBaseFragment
|
||||||
|
implements AppearAnimationCreator<Object> {
|
||||||
|
|
||||||
// how long we wait to clear a wrong pattern
|
// how long we wait to clear a wrong pattern
|
||||||
private static final int WRONG_PATTERN_CLEAR_TIMEOUT_MS = 2000;
|
private static final int WRONG_PATTERN_CLEAR_TIMEOUT_MS = 2000;
|
||||||
@@ -93,6 +110,9 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
private CharSequence mHeaderText;
|
private CharSequence mHeaderText;
|
||||||
private CharSequence mDetailsText;
|
private CharSequence mDetailsText;
|
||||||
|
|
||||||
|
private AppearAnimationUtils mAppearAnimationUtils;
|
||||||
|
private DisappearAnimationUtils mDisappearAnimationUtils;
|
||||||
|
|
||||||
// required constructor for fragments
|
// required constructor for fragments
|
||||||
public ConfirmLockPatternFragment() {
|
public ConfirmLockPatternFragment() {
|
||||||
|
|
||||||
@@ -144,6 +164,20 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
getActivity().finish();
|
getActivity().finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mAppearAnimationUtils = new AppearAnimationUtils(getContext(),
|
||||||
|
AppearAnimationUtils.DEFAULT_APPEAR_DURATION, 2f /* translationScale */,
|
||||||
|
1.3f /* delayScale */, AnimationUtils.loadInterpolator(
|
||||||
|
getContext(), android.R.interpolator.linear_out_slow_in));
|
||||||
|
mDisappearAnimationUtils = new DisappearAnimationUtils(getContext(),
|
||||||
|
125, 4f /* translationScale */,
|
||||||
|
0.3f /* delayScale */, AnimationUtils.loadInterpolator(
|
||||||
|
getContext(), android.R.interpolator.fast_out_linear_in),
|
||||||
|
new AppearAnimationUtils.RowTranslationScaler() {
|
||||||
|
@Override
|
||||||
|
public float getRowTranslationScale(int row, int numRows) {
|
||||||
|
return (float)(numRows - row) / numRows;
|
||||||
|
}
|
||||||
|
});
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,6 +221,51 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void prepareEnterAnimation() {
|
||||||
|
super.prepareEnterAnimation();
|
||||||
|
mHeaderTextView.setAlpha(0f);
|
||||||
|
mCancelButton.setAlpha(0f);
|
||||||
|
mLockPatternView.setAlpha(0f);
|
||||||
|
mDetailsTextView.setAlpha(0f);
|
||||||
|
mFingerprintIcon.setAlpha(0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object[][] getActiveViews() {
|
||||||
|
ArrayList<ArrayList<Object>> result = new ArrayList<>();
|
||||||
|
result.add(new ArrayList<Object>(Collections.singletonList(mHeaderTextView)));
|
||||||
|
result.add(new ArrayList<Object>(Collections.singletonList(mDetailsTextView)));
|
||||||
|
if (mCancelButton.getVisibility() == View.VISIBLE) {
|
||||||
|
result.add(new ArrayList<Object>(Collections.singletonList(mCancelButton)));
|
||||||
|
}
|
||||||
|
LockPatternView.CellState[][] cellStates = mLockPatternView.getCellStates();
|
||||||
|
for (int i = 0; i < cellStates.length; i++) {
|
||||||
|
ArrayList<Object> row = new ArrayList<>();
|
||||||
|
for (int j = 0; j < cellStates[i].length; j++) {
|
||||||
|
row.add(cellStates[i][j]);
|
||||||
|
}
|
||||||
|
result.add(row);
|
||||||
|
}
|
||||||
|
if (mFingerprintIcon.getVisibility() == View.VISIBLE) {
|
||||||
|
result.add(new ArrayList<Object>(Collections.singletonList(mFingerprintIcon)));
|
||||||
|
}
|
||||||
|
Object[][] resultArr = new Object[result.size()][cellStates[0].length];
|
||||||
|
for (int i = 0; i < result.size(); i++) {
|
||||||
|
ArrayList<Object> row = result.get(i);
|
||||||
|
for (int j = 0; j < row.size(); j++) {
|
||||||
|
resultArr[i][j] = row.get(j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resultArr;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startEnterAnimation() {
|
||||||
|
super.startEnterAnimation();
|
||||||
|
mLockPatternView.setAlpha(1f);
|
||||||
|
mAppearAnimationUtils.startAnimation2d(getActiveViews(), null, this);
|
||||||
|
}
|
||||||
|
|
||||||
private void updateStage(Stage stage) {
|
private void updateStage(Stage stage) {
|
||||||
switch (stage) {
|
switch (stage) {
|
||||||
case NeedToUnlock:
|
case NeedToUnlock:
|
||||||
@@ -242,9 +321,27 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void authenticationSucceeded() {
|
protected void authenticationSucceeded() {
|
||||||
Intent intent = new Intent();
|
startDisappearAnimation(new Intent());
|
||||||
getActivity().setResult(Activity.RESULT_OK, intent);
|
}
|
||||||
getActivity().finish();
|
|
||||||
|
private void startDisappearAnimation(final Intent intent) {
|
||||||
|
if (getActivity().getThemeResId() == R.style.Theme_ConfirmDeviceCredentialsDark) {
|
||||||
|
mLockPatternView.clearPattern();
|
||||||
|
mDisappearAnimationUtils.startAnimation2d(getActiveViews(),
|
||||||
|
new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
getActivity().setResult(RESULT_OK, intent);
|
||||||
|
getActivity().finish();
|
||||||
|
getActivity().overridePendingTransition(
|
||||||
|
R.anim.confirm_credential_close_enter,
|
||||||
|
R.anim.confirm_credential_close_exit);
|
||||||
|
}
|
||||||
|
}, this);
|
||||||
|
} else {
|
||||||
|
getActivity().setResult(RESULT_OK, intent);
|
||||||
|
getActivity().finish();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -357,8 +454,7 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
boolean matched, Intent intent, int timeoutMs) {
|
boolean matched, Intent intent, int timeoutMs) {
|
||||||
mLockPatternView.setEnabled(true);
|
mLockPatternView.setEnabled(true);
|
||||||
if (matched) {
|
if (matched) {
|
||||||
getActivity().setResult(Activity.RESULT_OK, intent);
|
startDisappearAnimation(intent);
|
||||||
getActivity().finish();
|
|
||||||
} else {
|
} else {
|
||||||
if (timeoutMs > 0) {
|
if (timeoutMs > 0) {
|
||||||
long deadline = mLockPatternUtils.setLockoutAttemptDeadline(
|
long deadline = mLockPatternUtils.setLockoutAttemptDeadline(
|
||||||
@@ -394,5 +490,52 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
}
|
}
|
||||||
}.start();
|
}.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createAnimation(Object obj, long delay,
|
||||||
|
long duration, float translationY, final boolean appearing,
|
||||||
|
Interpolator interpolator,
|
||||||
|
final Runnable finishListener) {
|
||||||
|
if (obj instanceof LockPatternView.CellState) {
|
||||||
|
final LockPatternView.CellState animatedCell = (LockPatternView.CellState) obj;
|
||||||
|
if (appearing) {
|
||||||
|
animatedCell.scale = 0.0f;
|
||||||
|
animatedCell.alpha = 1.0f;
|
||||||
|
}
|
||||||
|
animatedCell.translateY = appearing ? translationY : 0;
|
||||||
|
ValueAnimator animator = ValueAnimator.ofFloat(animatedCell.translateY,
|
||||||
|
appearing ? 0 : translationY);
|
||||||
|
animator.setInterpolator(interpolator);
|
||||||
|
animator.setDuration(duration);
|
||||||
|
animator.setStartDelay(delay);
|
||||||
|
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
float animatedFraction = animation.getAnimatedFraction();
|
||||||
|
if (appearing) {
|
||||||
|
animatedCell.scale = animatedFraction;
|
||||||
|
} else {
|
||||||
|
animatedCell.alpha = 1 - animatedFraction;
|
||||||
|
}
|
||||||
|
animatedCell.translateY = (float) animation.getAnimatedValue();
|
||||||
|
mLockPatternView.invalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (finishListener != null) {
|
||||||
|
animator.addListener(new AnimatorListenerAdapter() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationEnd(Animator animation) {
|
||||||
|
finishListener.run();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
animator.start();
|
||||||
|
mLockPatternView.invalidate();
|
||||||
|
} else {
|
||||||
|
mAppearAnimationUtils.createAnimation((View) obj, delay, duration, translationY,
|
||||||
|
appearing, interpolator, finishListener);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -18,7 +18,6 @@ package com.android.settings.fingerprint;
|
|||||||
|
|
||||||
import android.hardware.fingerprint.FingerprintManager;
|
import android.hardware.fingerprint.FingerprintManager;
|
||||||
import android.os.CancellationSignal;
|
import android.os.CancellationSignal;
|
||||||
import android.os.Vibrator;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
@@ -31,8 +30,6 @@ import com.android.settings.R;
|
|||||||
public class FingerprintUiHelper extends FingerprintManager.AuthenticationCallback {
|
public class FingerprintUiHelper extends FingerprintManager.AuthenticationCallback {
|
||||||
|
|
||||||
private static final long ERROR_TIMEOUT = 1300;
|
private static final long ERROR_TIMEOUT = 1300;
|
||||||
private static final long[] FP_ERROR_VIBRATE_PATTERN = new long[] {0, 30, 100, 30};
|
|
||||||
private static final long[] FP_SUCCESS_VIBRATE_PATTERN = new long[] {0, 30};
|
|
||||||
|
|
||||||
private ImageView mIcon;
|
private ImageView mIcon;
|
||||||
private TextView mErrorTextView;
|
private TextView mErrorTextView;
|
||||||
@@ -92,7 +89,7 @@ public class FingerprintUiHelper extends FingerprintManager.AuthenticationCallba
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
|
public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
|
||||||
vibrateFingerprintSuccess();
|
mIcon.setImageResource(R.drawable.ic_fingerprint_success);
|
||||||
mCallback.onAuthenticated();
|
mCallback.onAuthenticated();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,21 +98,12 @@ public class FingerprintUiHelper extends FingerprintManager.AuthenticationCallba
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
vibrateFingerprintError();
|
|
||||||
mIcon.setImageResource(R.drawable.ic_fingerprint_error);
|
mIcon.setImageResource(R.drawable.ic_fingerprint_error);
|
||||||
mErrorTextView.setText(error);
|
mErrorTextView.setText(error);
|
||||||
mErrorTextView.removeCallbacks(mResetErrorTextRunnable);
|
mErrorTextView.removeCallbacks(mResetErrorTextRunnable);
|
||||||
mErrorTextView.postDelayed(mResetErrorTextRunnable, ERROR_TIMEOUT);
|
mErrorTextView.postDelayed(mResetErrorTextRunnable, ERROR_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void vibrateFingerprintError() {
|
|
||||||
mIcon.getContext().getSystemService(Vibrator.class).vibrate(FP_ERROR_VIBRATE_PATTERN, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void vibrateFingerprintSuccess() {
|
|
||||||
mIcon.getContext().getSystemService(Vibrator.class).vibrate(FP_SUCCESS_VIBRATE_PATTERN, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Runnable mResetErrorTextRunnable = new Runnable() {
|
private Runnable mResetErrorTextRunnable = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
Reference in New Issue
Block a user