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

Commit 67302596 authored by Miranda Kephart's avatar Miranda Kephart Committed by android-build-merger
Browse files

Merge "Add white edgelights to AOSP" into qt-dev

am: 0bcd6984

Change-Id: I32e623a718404bb536ec84aa9fa33544c0cae799
parents fe9e9120 0bcd6984
Loading
Loading
Loading
Loading
+23 −0
Original line number Original line Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ Copyright (C) 2019 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
  -->

<com.android.systemui.assist.ui.InvocationLightsView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom"
    android:visibility="gone"/>
+6 −3
Original line number Original line Diff line number Diff line
@@ -174,6 +174,9 @@
    <!-- Logout button -->
    <!-- Logout button -->
    <color name="logout_button_bg_color">#ccffffff</color>
    <color name="logout_button_bg_color">#ccffffff</color>


    <!-- Color for the Assistant invocation lights -->
    <color name="default_invocation_lights_color">#ffffffff</color>         <!-- white -->

    <!-- GM2 colors -->
    <!-- GM2 colors -->
    <color name="GM2_grey_50">#F8F9FA</color>
    <color name="GM2_grey_50">#F8F9FA</color>
    <color name="GM2_grey_100">#F1F3F4</color>
    <color name="GM2_grey_100">#F1F3F4</color>
+73 −16
Original line number Original line Diff line number Diff line
@@ -40,8 +40,11 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.settingslib.applications.InterestingConfigChanges;
import com.android.settingslib.applications.InterestingConfigChanges;
import com.android.systemui.ConfigurationChangedReceiver;
import com.android.systemui.ConfigurationChangedReceiver;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.R;
import com.android.systemui.SysUiServiceProvider;
import com.android.systemui.SysUiServiceProvider;
import com.android.systemui.assist.ui.DefaultUiController;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;


@@ -50,6 +53,40 @@ import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 */
 */
public class AssistManager implements ConfigurationChangedReceiver {
public class AssistManager implements ConfigurationChangedReceiver {


    /**
     * Controls the UI for showing Assistant invocation progress.
     */
    public interface UiController {
        /**
         * Updates the invocation progress.
         *
         * @param type     one of INVOCATION_TYPE_GESTURE, INVOCATION_TYPE_ACTIVE_EDGE,
         *                 INVOCATION_TYPE_VOICE, INVOCATION_TYPE_QUICK_SEARCH_BAR,
         *                 INVOCATION_HOME_BUTTON_LONG_PRESS
         * @param progress a float between 0 and 1 inclusive. 0 represents the beginning of the
         *                 gesture; 1 represents the end.
         */
        void onInvocationProgress(int type, float progress);

        /**
         * Called when an invocation gesture completes.
         *
         * @param velocity the speed of the invocation gesture, in pixels per millisecond. For
         *                 drags, this is 0.
         */
        void onGestureCompletion(float velocity);

        /**
         * Called with the Bundle from VoiceInteractionSessionListener.onSetUiHints.
         */
        void processBundle(Bundle hints);

        /**
         * Hides the UI.
         */
        void hide();
    }

    private static final String TAG = "AssistManager";
    private static final String TAG = "AssistManager";


    // Note that VERBOSE logging may leak PII (e.g. transcription contents).
    // Note that VERBOSE logging may leak PII (e.g. transcription contents).
@@ -76,6 +113,7 @@ public class AssistManager implements ConfigurationChangedReceiver {
    private final InterestingConfigChanges mInterestingConfigChanges;
    private final InterestingConfigChanges mInterestingConfigChanges;
    private final PhoneStateMonitor mPhoneStateMonitor;
    private final PhoneStateMonitor mPhoneStateMonitor;
    private final AssistHandleBehaviorController mHandleController;
    private final AssistHandleBehaviorController mHandleController;
    private final UiController mUiController;


    private AssistOrbContainer mView;
    private AssistOrbContainer mView;
    private final DeviceProvisionedController mDeviceProvisionedController;
    private final DeviceProvisionedController mDeviceProvisionedController;
@@ -119,6 +157,23 @@ public class AssistManager implements ConfigurationChangedReceiver {
                | ActivityInfo.CONFIG_SCREEN_LAYOUT | ActivityInfo.CONFIG_ASSETS_PATHS);
                | ActivityInfo.CONFIG_SCREEN_LAYOUT | ActivityInfo.CONFIG_ASSETS_PATHS);
        onConfigurationChanged(context.getResources().getConfiguration());
        onConfigurationChanged(context.getResources().getConfiguration());
        mShouldEnableOrb = !ActivityManager.isLowRamDeviceStatic();
        mShouldEnableOrb = !ActivityManager.isLowRamDeviceStatic();

        mUiController = new DefaultUiController(mContext);

        OverviewProxyService overviewProxy = Dependency.get(OverviewProxyService.class);
        overviewProxy.addCallback(new OverviewProxyService.OverviewProxyListener() {
            @Override
            public void onAssistantProgress(float progress) {
                // Progress goes from 0 to 1 to indicate how close the assist gesture is to
                // completion.
                onInvocationProgress(INVOCATION_TYPE_GESTURE, progress);
            }

            @Override
            public void onAssistantGestureCompletion(float velocity) {
                onGestureCompletion(velocity);
            }
        });
    }
    }


    protected void registerVoiceInteractionSessionListener() {
    protected void registerVoiceInteractionSessionListener() {
@@ -196,21 +251,23 @@ public class AssistManager implements ConfigurationChangedReceiver {
        // Logs assistant start with invocation type.
        // Logs assistant start with invocation type.
        MetricsLogger.action(
        MetricsLogger.action(
                new LogMaker(MetricsEvent.ASSISTANT)
                new LogMaker(MetricsEvent.ASSISTANT)
                    .setType(MetricsEvent.TYPE_OPEN).setSubtype(args.getInt(INVOCATION_TYPE_KEY)));
                        .setType(MetricsEvent.TYPE_OPEN).setSubtype(
                        args.getInt(INVOCATION_TYPE_KEY)));
        startAssistInternal(args, assistComponent, isService);
        startAssistInternal(args, assistComponent, isService);
    }
    }


    /** Called when the user is performing an assistant invocation action (e.g. Active Edge) */
    /** Called when the user is performing an assistant invocation action (e.g. Active Edge) */
    public void onInvocationProgress(int type, float progress) {
    public void onInvocationProgress(int type, float progress) {
        // intentional no-op, vendor's AssistManager implementation should override if needed.
        mUiController.onInvocationProgress(type, progress);
    }
    }


    /** Called when the user has invoked the assistant with the incoming velocity, in pixels per
    /**
     * Called when the user has invoked the assistant with the incoming velocity, in pixels per
     * millisecond. For invocations without a velocity (e.g. slow drag), the velocity is set to
     * millisecond. For invocations without a velocity (e.g. slow drag), the velocity is set to
     * zero.
     * zero.
     */
     */
    public void onAssistantGestureCompletion(float velocity) {
    public void onGestureCompletion(float velocity) {
        // intentional no-op, vendor's AssistManager implementation should override if needed.
        mUiController.onGestureCompletion(velocity);
    }
    }


    public void hideAssist() {
    public void hideAssist() {
+65 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2019 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.assist.ui;

import android.graphics.Path;

/**
 * Describes paths for circular rounded device corners.
 */
public final class CircularCornerPathRenderer extends CornerPathRenderer {

    private final int mCornerRadiusBottom;
    private final int mCornerRadiusTop;
    private final int mHeight;
    private final int mWidth;
    private final Path mPath = new Path();

    public CircularCornerPathRenderer(int cornerRadiusBottom, int cornerRadiusTop,
            int width, int height) {
        mCornerRadiusBottom = cornerRadiusBottom;
        mCornerRadiusTop = cornerRadiusTop;
        mHeight = height;
        mWidth = width;
    }

    @Override // CornerPathRenderer
    public Path getCornerPath(Corner corner) {
        mPath.reset();
        switch (corner) {
            case BOTTOM_LEFT:
                mPath.moveTo(0, mHeight - mCornerRadiusBottom);
                mPath.arcTo(0, mHeight - mCornerRadiusBottom * 2, mCornerRadiusBottom * 2, mHeight,
                        180, -90, true);
                break;
            case BOTTOM_RIGHT:
                mPath.moveTo(mWidth - mCornerRadiusBottom, mHeight);
                mPath.arcTo(mWidth - mCornerRadiusBottom * 2, mHeight - mCornerRadiusBottom * 2,
                        mWidth, mHeight, 90, -90, true);
                break;
            case TOP_RIGHT:
                mPath.moveTo(mWidth, mCornerRadiusTop);
                mPath.arcTo(mWidth - mCornerRadiusTop, 0, mWidth, mCornerRadiusTop, 0, -90, true);
                break;
            case TOP_LEFT:
                mPath.moveTo(mCornerRadiusTop, 0);
                mPath.arcTo(0, 0, mCornerRadiusTop, mCornerRadiusTop, 270, -90, true);
                break;
        }
        return mPath;
    }
}
+140 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2019 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.assist.ui;

import android.graphics.Path;
import android.graphics.PointF;

import java.util.ArrayList;
import java.util.List;

/**
 * Handles paths along device corners.
 */
public abstract class CornerPathRenderer {

    // The maximum delta between the corner curve and points approximating the corner curve.
    private static final float ACCEPTABLE_ERROR = 0.1f;

    /**
     * For convenience, labels the four device corners.
     *
     * Corners must be listed in CCW order, otherwise we'll break rotation.
     */
    public enum Corner {
        BOTTOM_LEFT,
        BOTTOM_RIGHT,
        TOP_RIGHT,
        TOP_LEFT
    }

    /**
     * Returns the path along the inside of a corner (centered insetAmountPx from the corner's
     * edge).
     */
    public Path getInsetPath(Corner corner, float insetAmountPx) {
        return approximateInnerPath(getCornerPath(corner), -insetAmountPx);
    }

    /**
     * Returns the path of a corner (centered on the exact corner). Must be implemented by extending
     * classes, based on the device-specific rounded corners. A default implementation for circular
     * corners is provided by CircularCornerPathRenderer.
     */
    public abstract Path getCornerPath(Corner corner);

    private Path approximateInnerPath(Path input, float delta) {
        List<PointF> points = shiftBy(getApproximatePoints(input), delta);
        return toPath(points);
    }

    private ArrayList<PointF> getApproximatePoints(Path path) {
        float[] rawInput = path.approximate(ACCEPTABLE_ERROR);

        ArrayList<PointF> output = new ArrayList<>();

        for (int i = 0; i < rawInput.length; i = i + 3) {
            output.add(new PointF(rawInput[i + 1], rawInput[i + 2]));
        }

        return output;
    }

    private ArrayList<PointF> shiftBy(ArrayList<PointF> input, float delta) {
        ArrayList<PointF> output = new ArrayList<>();

        for (int i = 0; i < input.size(); i++) {
            PointF point = input.get(i);
            PointF normal = normalAt(input, i);
            PointF shifted =
                    new PointF(point.x + (normal.x * delta), point.y + (normal.y * delta));
            output.add(shifted);
        }
        return output;
    }

    private Path toPath(List<PointF> points) {
        Path path = new Path();
        if (points.size() > 0) {
            path.moveTo(points.get(0).x, points.get(0).y);
            for (PointF point : points.subList(1, points.size())) {
                path.lineTo(point.x, point.y);
            }
        }
        return path;
    }

    private PointF normalAt(List<PointF> points, int index) {
        PointF d1;
        if (index == 0) {
            d1 = new PointF(0, 0);
        } else {
            PointF point = points.get(index);
            PointF previousPoint = points.get(index - 1);
            d1 = new PointF((point.x - previousPoint.x), (point.y - previousPoint.y));
        }

        PointF d2;
        if (index == (points.size() - 1)) {
            d2 = new PointF(0, 0);
        } else {
            PointF point = points.get(index);
            PointF nextPoint = points.get(index + 1);
            d2 = new PointF((nextPoint.x - point.x), (nextPoint.y - point.y));
        }

        return rotate90Ccw(normalize(new PointF(d1.x + d2.x, d1.y + d2.y)));
    }

    private PointF rotate90Ccw(PointF input) {
        return new PointF(-input.y, input.x);
    }

    private float magnitude(PointF point) {
        return (float) Math.sqrt((point.x * point.x) + (point.y * point.y));
    }

    private PointF normalize(PointF point) {
        float magnitude = magnitude(point);
        if (magnitude == 0.f) {
            return point;
        }

        float normal = 1 / magnitude;
        return new PointF((point.x * normal), (point.y * normal));
    }
}
Loading