diff --git a/src/com/android/settings/biometrics/face/FaceEnrollAnimationDrawable.java b/src/com/android/settings/biometrics/face/FaceEnrollAnimationDrawable.java index 5be7c5331d3..b6ad565bad2 100644 --- a/src/com/android/settings/biometrics/face/FaceEnrollAnimationDrawable.java +++ b/src/com/android/settings/biometrics/face/FaceEnrollAnimationDrawable.java @@ -29,6 +29,7 @@ import android.graphics.Rect; import android.graphics.drawable.Drawable; import com.android.settings.biometrics.BiometricEnrollSidecar; +import com.android.settings.overlay.FeatureFactory; /** * A drawable containing the circle cutout as well as the animations. @@ -41,17 +42,17 @@ public class FaceEnrollAnimationDrawable extends Drawable private static final int BORDER_BOUNDS = 20; private final Context mContext; - private final ParticleCollection.Listener mListener; + private final FaceFeatureProvider.Listener mListener; private Rect mBounds; private final Paint mSquarePaint; private final Paint mCircleCutoutPaint; - private ParticleCollection mParticleCollection; + private FaceFeatureProvider.EnrollingAnimation mEnrollingAnimation; private TimeAnimator mTimeAnimator; - private final ParticleCollection.Listener mAnimationListener - = new ParticleCollection.Listener() { + private final FaceFeatureProvider.Listener mAnimationListener + = new FaceFeatureProvider.Listener() { @Override public void onEnrolled() { if (mTimeAnimator != null && mTimeAnimator.isStarted()) { @@ -61,7 +62,7 @@ public class FaceEnrollAnimationDrawable extends Drawable } }; - public FaceEnrollAnimationDrawable(Context context, ParticleCollection.Listener listener) { + public FaceEnrollAnimationDrawable(Context context, FaceFeatureProvider.Listener listener) { mContext = context; mListener = listener; @@ -77,29 +78,29 @@ public class FaceEnrollAnimationDrawable extends Drawable @Override public void onEnrollmentHelp(int helpMsgId, CharSequence helpString) { - mParticleCollection.onEnrollmentHelp(helpMsgId, helpString); + mEnrollingAnimation.onEnrollmentHelp(helpMsgId, helpString); } @Override public void onEnrollmentError(int errMsgId, CharSequence errString) { - mParticleCollection.onEnrollmentError(errMsgId, errString); + mEnrollingAnimation.onEnrollmentError(errMsgId, errString); } @Override public void onEnrollmentProgressChange(int steps, int remaining) { - mParticleCollection.onEnrollmentProgressChange(steps, remaining); + mEnrollingAnimation.onEnrollmentProgressChange(steps, remaining); } @Override protected void onBoundsChange(Rect bounds) { mBounds = bounds; - mParticleCollection = - new ParticleCollection(mContext, mAnimationListener, bounds, BORDER_BOUNDS); + mEnrollingAnimation = FeatureFactory.getFactory(mContext).getFaceFeatureProvider() + .getEnrollingAnimation(mContext, mAnimationListener, bounds, BORDER_BOUNDS); if (mTimeAnimator == null) { mTimeAnimator = new TimeAnimator(); mTimeAnimator.setTimeListener((animation, totalTimeMs, deltaTimeMs) -> { - mParticleCollection.update(totalTimeMs, deltaTimeMs); + mEnrollingAnimation.update(totalTimeMs, deltaTimeMs); FaceEnrollAnimationDrawable.this.invalidateSelf(); }); mTimeAnimator.start(); @@ -121,7 +122,7 @@ public class FaceEnrollAnimationDrawable extends Drawable mBounds.height() / 2 - BORDER_BOUNDS, mCircleCutoutPaint); // Draw the animation - mParticleCollection.draw(canvas); + mEnrollingAnimation.draw(canvas); canvas.restore(); } diff --git a/src/com/android/settings/biometrics/face/FaceEnrollEnrolling.java b/src/com/android/settings/biometrics/face/FaceEnrollEnrolling.java index 37b949c7709..727d74ac93b 100644 --- a/src/com/android/settings/biometrics/face/FaceEnrollEnrolling.java +++ b/src/com/android/settings/biometrics/face/FaceEnrollEnrolling.java @@ -47,7 +47,7 @@ public class FaceEnrollEnrolling extends BiometricsEnrollEnrolling { private boolean mShouldFinishOnStop = true; private FaceEnrollPreviewFragment mPreviewFragment; - private ParticleCollection.Listener mListener = new ParticleCollection.Listener() { + private FaceFeatureProvider.Listener mListener = new FaceFeatureProvider.Listener() { @Override public void onEnrolled() { FaceEnrollEnrolling.this.launchFinish(mToken); diff --git a/src/com/android/settings/biometrics/face/FaceEnrollPreviewFragment.java b/src/com/android/settings/biometrics/face/FaceEnrollPreviewFragment.java index a5435845c06..a3708751cf4 100644 --- a/src/com/android/settings/biometrics/face/FaceEnrollPreviewFragment.java +++ b/src/com/android/settings/biometrics/face/FaceEnrollPreviewFragment.java @@ -63,7 +63,7 @@ public class FaceEnrollPreviewFragment extends InstrumentedPreferenceFragment private CameraCaptureSession mCaptureSession; private CaptureRequest mPreviewRequest; private Size mPreviewSize; - private ParticleCollection.Listener mListener; + private FaceFeatureProvider.Listener mListener; // View used to contain the circular cutout and enrollment animation drawable private ImageView mCircleView; @@ -75,8 +75,8 @@ public class FaceEnrollPreviewFragment extends InstrumentedPreferenceFragment private FaceSquareTextureView mTextureView; // Listener sent to the animation drawable - private final ParticleCollection.Listener mAnimationListener - = new ParticleCollection.Listener() { + private final FaceFeatureProvider.Listener mAnimationListener + = new FaceFeatureProvider.Listener() { @Override public void onEnrolled() { mListener.onEnrolled(); @@ -234,7 +234,7 @@ public class FaceEnrollPreviewFragment extends InstrumentedPreferenceFragment mAnimationDrawable.onEnrollmentProgressChange(steps, remaining); } - public void setListener(ParticleCollection.Listener listener) { + public void setListener(FaceFeatureProvider.Listener listener) { mListener = listener; } diff --git a/src/com/android/settings/biometrics/face/FaceFeatureProvider.java b/src/com/android/settings/biometrics/face/FaceFeatureProvider.java new file mode 100644 index 00000000000..e2f62d3a9af --- /dev/null +++ b/src/com/android/settings/biometrics/face/FaceFeatureProvider.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2018 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.biometrics.face; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Rect; + +/** + * Feature provider for face authentication. + */ +public interface FaceFeatureProvider { + + interface EnrollingAnimation { + void onEnrollmentHelp(int helpMsgId, CharSequence helpString); + void onEnrollmentError(int errMsgId, CharSequence errString); + void onEnrollmentProgressChange(int steps, int remaining); + void draw(Canvas canvas); + void update(long t, long dt); + } + + interface Listener { + void onEnrolled(); + } + + EnrollingAnimation getEnrollingAnimation(Context context, Listener listener, Rect bounds, + int borderWidth); +} diff --git a/src/com/android/settings/biometrics/face/FaceFeatureProviderImpl.java b/src/com/android/settings/biometrics/face/FaceFeatureProviderImpl.java new file mode 100644 index 00000000000..3f656696afa --- /dev/null +++ b/src/com/android/settings/biometrics/face/FaceFeatureProviderImpl.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2018 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.biometrics.face; + +import android.content.Context; +import android.graphics.Rect; + +public class FaceFeatureProviderImpl implements FaceFeatureProvider { + @Override + public EnrollingAnimation getEnrollingAnimation(Context context, Listener listener, Rect bounds, + int borderWidth) { + return new ParticleCollection(context, listener, bounds, borderWidth); + } +} diff --git a/src/com/android/settings/biometrics/face/ParticleCollection.java b/src/com/android/settings/biometrics/face/ParticleCollection.java index 399beec3abd..b345ab5f945 100644 --- a/src/com/android/settings/biometrics/face/ParticleCollection.java +++ b/src/com/android/settings/biometrics/face/ParticleCollection.java @@ -35,7 +35,7 @@ import java.util.List; * are updated/drawn in a special order so that the overlap is correct during the final completion * effect. */ -public class ParticleCollection implements BiometricEnrollSidecar.Listener { +public class ParticleCollection implements FaceFeatureProviderImpl.EnrollingAnimation { private static final String TAG = "AnimationController"; @@ -49,11 +49,7 @@ public class ParticleCollection implements BiometricEnrollSidecar.Listener { private final List mParticleList; private final List mPrimariesInProgress; // primary particles not done animating yet private int mState; - private Listener mListener; - - public interface Listener { - void onEnrolled(); - } + private FaceFeatureProvider.Listener mListener; private final AnimationParticle.Listener mParticleListener = new AnimationParticle.Listener() { @Override @@ -72,7 +68,8 @@ public class ParticleCollection implements BiometricEnrollSidecar.Listener { } }; - public ParticleCollection(Context context, Listener listener, Rect bounds, int borderWidth) { + public ParticleCollection(Context context, FaceFeatureProvider.Listener listener, Rect bounds, + int borderWidth) { mParticleList = new ArrayList<>(); mListener = listener; @@ -103,12 +100,14 @@ public class ParticleCollection implements BiometricEnrollSidecar.Listener { updateState(STATE_STARTED); } + @Override public void update(long t, long dt) { for (int i = 0; i < mParticleList.size(); i++) { mParticleList.get(i).update(t, dt); } } + @Override public void draw(Canvas canvas) { for (int i = 0; i < mParticleList.size(); i++) { mParticleList.get(i).draw(canvas); diff --git a/src/com/android/settings/overlay/FeatureFactory.java b/src/com/android/settings/overlay/FeatureFactory.java index a52619b3a6f..184ccc8b7ab 100644 --- a/src/com/android/settings/overlay/FeatureFactory.java +++ b/src/com/android/settings/overlay/FeatureFactory.java @@ -23,6 +23,7 @@ import android.util.Log; import com.android.settings.R; import com.android.settings.accounts.AccountFeatureProvider; import com.android.settings.applications.ApplicationFeatureProvider; +import com.android.settings.biometrics.face.FaceFeatureProvider; import com.android.settings.dashboard.DashboardFeatureProvider; import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider; import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider; @@ -111,6 +112,8 @@ public abstract class FeatureFactory { public abstract ContextualCardFeatureProvider getContextualCardFeatureProvider(); + public abstract FaceFeatureProvider getFaceFeatureProvider(); + public static final class FactoryNotFoundException extends RuntimeException { public FactoryNotFoundException(Throwable throwable) { super("Unable to create factory. Did you misconfigure Proguard?", throwable); diff --git a/src/com/android/settings/overlay/FeatureFactoryImpl.java b/src/com/android/settings/overlay/FeatureFactoryImpl.java index 3515ac06a48..88c09d036a2 100644 --- a/src/com/android/settings/overlay/FeatureFactoryImpl.java +++ b/src/com/android/settings/overlay/FeatureFactoryImpl.java @@ -28,6 +28,8 @@ import com.android.settings.accounts.AccountFeatureProvider; import com.android.settings.accounts.AccountFeatureProviderImpl; import com.android.settings.applications.ApplicationFeatureProvider; import com.android.settings.applications.ApplicationFeatureProviderImpl; +import com.android.settings.biometrics.face.FaceFeatureProvider; +import com.android.settings.biometrics.face.FaceFeatureProviderImpl; import com.android.settings.connecteddevice.dock.DockUpdaterFeatureProviderImpl; import com.android.settings.core.instrumentation.SettingsMetricsFeatureProvider; import com.android.settings.dashboard.DashboardFeatureProvider; @@ -78,6 +80,7 @@ public class FeatureFactoryImpl extends FeatureFactory { private AccountFeatureProvider mAccountFeatureProvider; private PanelFeatureProvider mPanelFeatureProvider; private ContextualCardFeatureProvider mContextualCardFeatureProvider; + private FaceFeatureProvider mFaceFeatureProvider; @Override public SupportFeatureProvider getSupportFeatureProvider(Context context) { @@ -224,10 +227,19 @@ public class FeatureFactoryImpl extends FeatureFactory { return mPanelFeatureProvider; } + @Override public ContextualCardFeatureProvider getContextualCardFeatureProvider() { if (mContextualCardFeatureProvider == null) { mContextualCardFeatureProvider = new ContextualCardFeatureProviderImpl(); } return mContextualCardFeatureProvider; } + + @Override + public FaceFeatureProvider getFaceFeatureProvider() { + if (mFaceFeatureProvider == null) { + mFaceFeatureProvider = new FaceFeatureProviderImpl(); + } + return mFaceFeatureProvider; + } } diff --git a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java index ef07fd4a880..e0b8646df25 100644 --- a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java +++ b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java @@ -23,6 +23,7 @@ import android.content.Context; import com.android.settings.accounts.AccountFeatureProvider; import com.android.settings.applications.ApplicationFeatureProvider; +import com.android.settings.biometrics.face.FaceFeatureProvider; import com.android.settings.dashboard.DashboardFeatureProvider; import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider; import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider; @@ -64,6 +65,7 @@ public class FakeFeatureFactory extends FeatureFactory { public final AssistGestureFeatureProvider assistGestureFeatureProvider; public final AccountFeatureProvider mAccountFeatureProvider; public final ContextualCardFeatureProvider mContextualCardFeatureProvider; + public final FaceFeatureProvider mFaceFeatureProvider; public PanelFeatureProvider panelFeatureProvider; public SlicesFeatureProvider slicesFeatureProvider; @@ -108,6 +110,7 @@ public class FakeFeatureFactory extends FeatureFactory { mAccountFeatureProvider = mock(AccountFeatureProvider.class); mContextualCardFeatureProvider = mock(ContextualCardFeatureProvider.class); panelFeatureProvider = mock(PanelFeatureProvider.class); + mFaceFeatureProvider = mock(FaceFeatureProvider.class); } @Override @@ -195,7 +198,13 @@ public class FakeFeatureFactory extends FeatureFactory { return panelFeatureProvider; } + @Override public ContextualCardFeatureProvider getContextualCardFeatureProvider() { return mContextualCardFeatureProvider; } + + @Override + public FaceFeatureProvider getFaceFeatureProvider() { + return mFaceFeatureProvider; + } }