Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ac276482 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Extract plugin interface for lockscreen camera button"

parents 7f5c470f b59f46fb
Loading
Loading
Loading
Loading
+41 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2016 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.systemui.plugins;

import android.content.Intent;
import android.graphics.drawable.Drawable;

/**
 * An Intent Button represents a triggerable element in SysUI that consists of an
 * Icon and an intent to trigger when it is activated (clicked, swiped, etc.).
 */
public interface IntentButtonProvider extends Plugin {

    public static final int VERSION = 1;

    public IntentButton getIntentButton();

    public interface IntentButton {
        public static class IconState {
            public boolean isVisible = true;
            public CharSequence contentDescription = null;
            public Drawable drawable;
        }

        public IconState getIcon();

        public Intent getIntent();
    }
}
+186 −76
Original line number Original line Diff line number Diff line
@@ -61,6 +61,11 @@ import com.android.systemui.EventLogTags;
import com.android.systemui.Interpolators;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.R;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.plugins.IntentButtonProvider;
import com.android.systemui.plugins.IntentButtonProvider.IntentButton;
import com.android.systemui.plugins.IntentButtonProvider.IntentButton.IconState;
import com.android.systemui.plugins.PluginListener;
import com.android.systemui.plugins.PluginManager;
import com.android.systemui.plugins.qs.QSContainer.ActivityStarter;
import com.android.systemui.plugins.qs.QSContainer.ActivityStarter;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.KeyguardAffordanceView;
import com.android.systemui.statusbar.KeyguardAffordanceView;
@@ -86,6 +91,11 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
    public static final String EXTRA_CAMERA_LAUNCH_SOURCE
    public static final String EXTRA_CAMERA_LAUNCH_SOURCE
            = "com.android.systemui.camera_launch_source";
            = "com.android.systemui.camera_launch_source";


    private static final String LEFT_BUTTON_PLUGIN
            = "com.android.systemui.action.PLUGIN_LOCKSCREEN_LEFT_BUTTON";
    private static final String RIGHT_BUTTON_PLUGIN
            = "com.android.systemui.action.PLUGIN_LOCKSCREEN_RIGHT_BUTTON";

    private static final Intent SECURE_CAMERA_INTENT =
    private static final Intent SECURE_CAMERA_INTENT =
            new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE)
            new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE)
                    .addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
                    .addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
@@ -95,7 +105,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
    private static final int DOZE_ANIMATION_STAGGER_DELAY = 48;
    private static final int DOZE_ANIMATION_STAGGER_DELAY = 48;
    private static final int DOZE_ANIMATION_ELEMENT_DURATION = 250;
    private static final int DOZE_ANIMATION_ELEMENT_DURATION = 250;


    private KeyguardAffordanceView mCameraImageView;
    private KeyguardAffordanceView mRightAffordanceView;
    private KeyguardAffordanceView mLeftAffordanceView;
    private KeyguardAffordanceView mLeftAffordanceView;
    private LockIcon mLockIcon;
    private LockIcon mLockIcon;
    private TextView mIndicationText;
    private TextView mIndicationText;
@@ -132,6 +142,9 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
    private boolean mLeftIsVoiceAssist;
    private boolean mLeftIsVoiceAssist;
    private AssistManager mAssistManager;
    private AssistManager mAssistManager;


    private IntentButton mRightButton = new DefaultRightButton();
    private IntentButton mLeftButton = new DefaultLeftButton();

    public KeyguardBottomAreaView(Context context) {
    public KeyguardBottomAreaView(Context context) {
        this(context, null);
        this(context, null);
    }
    }
@@ -156,7 +169,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
            String label = null;
            String label = null;
            if (host == mLockIcon) {
            if (host == mLockIcon) {
                label = getResources().getString(R.string.unlock_label);
                label = getResources().getString(R.string.unlock_label);
            } else if (host == mCameraImageView) {
            } else if (host == mRightAffordanceView) {
                label = getResources().getString(R.string.camera_label);
                label = getResources().getString(R.string.camera_label);
            } else if (host == mLeftAffordanceView) {
            } else if (host == mLeftAffordanceView) {
                if (mLeftIsVoiceAssist) {
                if (mLeftIsVoiceAssist) {
@@ -175,7 +188,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
                    mPhoneStatusBar.animateCollapsePanels(
                    mPhoneStatusBar.animateCollapsePanels(
                            CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */);
                            CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */);
                    return true;
                    return true;
                } else if (host == mCameraImageView) {
                } else if (host == mRightAffordanceView) {
                    launchCamera(CAMERA_LAUNCH_SOURCE_AFFORDANCE);
                    launchCamera(CAMERA_LAUNCH_SOURCE_AFFORDANCE);
                    return true;
                    return true;
                } else if (host == mLeftAffordanceView) {
                } else if (host == mLeftAffordanceView) {
@@ -192,7 +205,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
        super.onFinishInflate();
        super.onFinishInflate();
        mLockPatternUtils = new LockPatternUtils(mContext);
        mLockPatternUtils = new LockPatternUtils(mContext);
        mPreviewContainer = (ViewGroup) findViewById(R.id.preview_container);
        mPreviewContainer = (ViewGroup) findViewById(R.id.preview_container);
        mCameraImageView = (KeyguardAffordanceView) findViewById(R.id.camera_button);
        mRightAffordanceView = (KeyguardAffordanceView) findViewById(R.id.camera_button);
        mLeftAffordanceView = (KeyguardAffordanceView) findViewById(R.id.left_button);
        mLeftAffordanceView = (KeyguardAffordanceView) findViewById(R.id.left_button);
        mLockIcon = (LockIcon) findViewById(R.id.lock_icon);
        mLockIcon = (LockIcon) findViewById(R.id.lock_icon);
        mIndicationText = (TextView) findViewById(R.id.keyguard_indication_text);
        mIndicationText = (TextView) findViewById(R.id.keyguard_indication_text);
@@ -207,15 +220,31 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
        inflateCameraPreview();
        inflateCameraPreview();
        mLockIcon.setOnClickListener(this);
        mLockIcon.setOnClickListener(this);
        mLockIcon.setOnLongClickListener(this);
        mLockIcon.setOnLongClickListener(this);
        mCameraImageView.setOnClickListener(this);
        mRightAffordanceView.setOnClickListener(this);
        mLeftAffordanceView.setOnClickListener(this);
        mLeftAffordanceView.setOnClickListener(this);
        initAccessibility();
        initAccessibility();
    }
    }


    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        PluginManager.getInstance(getContext()).addPluginListener(RIGHT_BUTTON_PLUGIN,
                mRightListener, IntentButtonProvider.VERSION, false /* Only allow one */);
        PluginManager.getInstance(getContext()).addPluginListener(LEFT_BUTTON_PLUGIN,
                mLeftListener, IntentButtonProvider.VERSION, false /* Only allow one */);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        PluginManager.getInstance(getContext()).removePluginListener(mRightListener);
        PluginManager.getInstance(getContext()).removePluginListener(mLeftListener);
    }

    private void initAccessibility() {
    private void initAccessibility() {
        mLockIcon.setAccessibilityDelegate(mAccessibilityDelegate);
        mLockIcon.setAccessibilityDelegate(mAccessibilityDelegate);
        mLeftAffordanceView.setAccessibilityDelegate(mAccessibilityDelegate);
        mLeftAffordanceView.setAccessibilityDelegate(mAccessibilityDelegate);
        mCameraImageView.setAccessibilityDelegate(mAccessibilityDelegate);
        mRightAffordanceView.setAccessibilityDelegate(mAccessibilityDelegate);
    }
    }


    @Override
    @Override
@@ -234,11 +263,11 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
                getResources().getDimensionPixelSize(
                getResources().getDimensionPixelSize(
                        com.android.internal.R.dimen.text_size_small_material));
                        com.android.internal.R.dimen.text_size_small_material));


        ViewGroup.LayoutParams lp = mCameraImageView.getLayoutParams();
        ViewGroup.LayoutParams lp = mRightAffordanceView.getLayoutParams();
        lp.width = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_width);
        lp.width = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_width);
        lp.height = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_height);
        lp.height = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_height);
        mCameraImageView.setLayoutParams(lp);
        mRightAffordanceView.setLayoutParams(lp);
        mCameraImageView.setImageDrawable(mContext.getDrawable(R.drawable.ic_camera_alt_24dp));
        updateRightAffordanceIcon();


        lp = mLockIcon.getLayoutParams();
        lp = mLockIcon.getLayoutParams();
        lp.width = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_width);
        lp.width = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_width);
@@ -253,6 +282,13 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
        updateLeftAffordanceIcon();
        updateLeftAffordanceIcon();
    }
    }


    private void updateRightAffordanceIcon() {
        IconState state = mRightButton.getIcon();
        mRightAffordanceView.setVisibility(state.isVisible ? View.VISIBLE : View.GONE);
        mRightAffordanceView.setImageDrawable(state.drawable);
        mRightAffordanceView.setContentDescription(state.contentDescription);
    }

    public void setActivityStarter(ActivityStarter activityStarter) {
    public void setActivityStarter(ActivityStarter activityStarter) {
        mActivityStarter = activityStarter;
        mActivityStarter = activityStarter;
    }
    }
@@ -279,11 +315,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
    }
    }


    private Intent getCameraIntent() {
    private Intent getCameraIntent() {
        KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
        return mRightButton.getIntent();
        boolean canSkipBouncer = updateMonitor.getUserCanSkipBouncer(
                KeyguardUpdateMonitor.getCurrentUser());
        boolean secure = mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser());
        return (secure && !canSkipBouncer) ? SECURE_CAMERA_INTENT : INSECURE_CAMERA_INTENT;
    }
    }


    /**
    /**
@@ -296,33 +328,19 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
    }
    }


    private void updateCameraVisibility() {
    private void updateCameraVisibility() {
        if (mCameraImageView == null) {
        if (mRightAffordanceView == null) {
            // Things are not set up yet; reply hazy, ask again later
            // Things are not set up yet; reply hazy, ask again later
            return;
            return;
        }
        }
        ResolveInfo resolved = resolveCameraIntent();
        mRightAffordanceView.setVisibility(mRightButton.getIcon().isVisible
        boolean visible = !isCameraDisabledByDpm() && resolved != null
                ? View.VISIBLE : View.GONE);
                && getResources().getBoolean(R.bool.config_keyguardShowCameraAffordance)
                && mUserSetupComplete;
        mCameraImageView.setVisibility(visible ? View.VISIBLE : View.GONE);
    }
    }


    private void updateLeftAffordanceIcon() {
    private void updateLeftAffordanceIcon() {
        mLeftIsVoiceAssist = canLaunchVoiceAssist();
        IconState state = mLeftButton.getIcon();
        int drawableId;
        mLeftAffordanceView.setVisibility(state.isVisible ? View.VISIBLE : View.GONE);
        int contentDescription;
        mLeftAffordanceView.setImageDrawable(state.drawable);
        boolean visible = mUserSetupComplete;
        mLeftAffordanceView.setContentDescription(state.contentDescription);
        if (mLeftIsVoiceAssist) {
            drawableId = R.drawable.ic_mic_26dp;
            contentDescription = R.string.accessibility_voice_assist_button;
        } else {
            visible &= isPhoneVisible();
            drawableId = R.drawable.ic_phone_24dp;
            contentDescription = R.string.accessibility_phone_button;
        }
        mLeftAffordanceView.setVisibility(visible ? View.VISIBLE : View.GONE);
        mLeftAffordanceView.setImageDrawable(mContext.getDrawable(drawableId));
        mLeftAffordanceView.setContentDescription(mContext.getString(contentDescription));
    }
    }


    public boolean isLeftVoiceAssist() {
    public boolean isLeftVoiceAssist() {
@@ -363,16 +381,16 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL


    @Override
    @Override
    public void onStateChanged(boolean accessibilityEnabled, boolean touchExplorationEnabled) {
    public void onStateChanged(boolean accessibilityEnabled, boolean touchExplorationEnabled) {
        mCameraImageView.setClickable(touchExplorationEnabled);
        mRightAffordanceView.setClickable(touchExplorationEnabled);
        mLeftAffordanceView.setClickable(touchExplorationEnabled);
        mLeftAffordanceView.setClickable(touchExplorationEnabled);
        mCameraImageView.setFocusable(accessibilityEnabled);
        mRightAffordanceView.setFocusable(accessibilityEnabled);
        mLeftAffordanceView.setFocusable(accessibilityEnabled);
        mLeftAffordanceView.setFocusable(accessibilityEnabled);
        mLockIcon.update();
        mLockIcon.update();
    }
    }


    @Override
    @Override
    public void onClick(View v) {
    public void onClick(View v) {
        if (v == mCameraImageView) {
        if (v == mRightAffordanceView) {
            launchCamera(CAMERA_LAUNCH_SOURCE_AFFORDANCE);
            launchCamera(CAMERA_LAUNCH_SOURCE_AFFORDANCE);
        } else if (v == mLeftAffordanceView) {
        } else if (v == mLeftAffordanceView) {
            launchLeftAffordance();
            launchLeftAffordance();
@@ -541,7 +559,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
                }
                }
            });
            });
        } else {
        } else {
            mActivityStarter.startActivity(PHONE_INTENT, false /* dismissShade */);
            mActivityStarter.startActivity(mLeftButton.getIntent(), false /* dismissShade */);
        }
        }
    }
    }


@@ -560,7 +578,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
    }
    }


    public KeyguardAffordanceView getRightView() {
    public KeyguardAffordanceView getRightView() {
        return mCameraImageView;
        return mRightAffordanceView;
    }
    }


    public View getLeftPreview() {
    public View getLeftPreview() {
@@ -613,7 +631,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
            mLeftPreview = mPreviewInflater.inflatePreviewFromService(
            mLeftPreview = mPreviewInflater.inflatePreviewFromService(
                    mAssistManager.getVoiceInteractorComponentName());
                    mAssistManager.getVoiceInteractorComponentName());
        } else {
        } else {
            mLeftPreview = mPreviewInflater.inflatePreview(PHONE_INTENT);
            mLeftPreview = mPreviewInflater.inflatePreview(mLeftButton.getIntent());
        }
        }
        if (mLeftPreview != null) {
        if (mLeftPreview != null) {
            mPreviewContainer.addView(mLeftPreview);
            mPreviewContainer.addView(mLeftPreview);
@@ -629,8 +647,8 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
        }
        }
        startFinishDozeAnimationElement(mLockIcon, delay);
        startFinishDozeAnimationElement(mLockIcon, delay);
        delay += DOZE_ANIMATION_STAGGER_DELAY;
        delay += DOZE_ANIMATION_STAGGER_DELAY;
        if (mCameraImageView.getVisibility() == View.VISIBLE) {
        if (mRightAffordanceView.getVisibility() == View.VISIBLE) {
            startFinishDozeAnimationElement(mCameraImageView, delay);
            startFinishDozeAnimationElement(mRightAffordanceView, delay);
        }
        }
        mIndicationText.setAlpha(0f);
        mIndicationText.setAlpha(0f);
        mIndicationText.animate()
        mIndicationText.animate()
@@ -724,4 +742,96 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
        updateLeftAffordance();
        updateLeftAffordance();
        inflateCameraPreview();
        inflateCameraPreview();
    }
    }

    private void setRightButton(IntentButton button) {
        mRightButton = button;
        updateRightAffordanceIcon();
        updateCameraVisibility();
        inflateCameraPreview();
    }

    private void setLeftButton(IntentButton button) {
        mLeftButton = button;
        mLeftIsVoiceAssist = false;
        updateLeftAffordance();
    }

    private final PluginListener<IntentButtonProvider> mRightListener =
            new PluginListener<IntentButtonProvider>() {
        @Override
        public void onPluginConnected(IntentButtonProvider plugin) {
            setRightButton(plugin.getIntentButton());
        }

        @Override
        public void onPluginDisconnected(IntentButtonProvider plugin) {
            setRightButton(new DefaultRightButton());
        }
    };

    private final PluginListener<IntentButtonProvider> mLeftListener =
            new PluginListener<IntentButtonProvider>() {
        @Override
        public void onPluginConnected(IntentButtonProvider plugin) {
            setLeftButton(plugin.getIntentButton());
        }

        @Override
        public void onPluginDisconnected(IntentButtonProvider plugin) {
            setLeftButton(new DefaultLeftButton());
        }
    };

    private class DefaultLeftButton implements IntentButton {

        private IconState mIconState = new IconState();

        @Override
        public IconState getIcon() {
            mLeftIsVoiceAssist = canLaunchVoiceAssist();
            if (mLeftIsVoiceAssist) {
                mIconState.isVisible = mUserSetupComplete;
                mIconState.drawable = mContext.getDrawable(R.drawable.ic_mic_26dp);
                mIconState.contentDescription = mContext.getString(
                        R.string.accessibility_voice_assist_button);
            } else {
                mIconState.isVisible = mUserSetupComplete && isPhoneVisible();
                mIconState.drawable = mContext.getDrawable(R.drawable.ic_phone_24dp);
                mIconState.contentDescription = mContext.getString(
                        R.string.accessibility_phone_button);
            }
            return mIconState;
        }

        @Override
        public Intent getIntent() {
            return PHONE_INTENT;
        }
    }

    private class DefaultRightButton implements IntentButton {

        private IconState mIconState = new IconState();

        @Override
        public IconState getIcon() {
            ResolveInfo resolved = resolveCameraIntent();
            mIconState.isVisible = !isCameraDisabledByDpm() && resolved != null
                    && getResources().getBoolean(R.bool.config_keyguardShowCameraAffordance)
                    && mUserSetupComplete;
            mIconState.drawable = mContext.getDrawable(R.drawable.ic_camera_alt_24dp);
            mIconState.contentDescription =
                    mContext.getString(R.string.accessibility_camera_button);
            return mIconState;
        }

        @Override
        public Intent getIntent() {
            KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
            boolean canSkipBouncer = updateMonitor.getUserCanSkipBouncer(
                    KeyguardUpdateMonitor.getCurrentUser());
            boolean secure = mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser());
            return (secure && !canSkipBouncer) ? SECURE_CAMERA_INTENT : INSECURE_CAMERA_INTENT;
        }
    }
}
}