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

Commit eefd167d authored by oreiche's avatar oreiche Committed by Joey Rizzoli
Browse files

base: LocationTile detail



* Contributors:

@thecrazyskull
@carlosavignano
@oreiche
@evana

Change-Id: I968e26b6e5e4ad0acdb347c4acc03994b73ca74b
Signed-off-by: default avatarAlex Naidis <alex.naidis@linux.com>
parent 3de28072
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
<!--
    Copyright (C) 2017 The LineageOS Project
    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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="64dp"
        android:height="64dp"
        android:viewportWidth="48.0"
        android:viewportHeight="48.0">

    <path
        android:fillColor="#4DFFFFFF"
        android:pathData="M24.0,4.0c-7.7,0.0 -14.0,6.3 -14.0,14.0c0.0,10.5 14.0,26.0 14.0,26.0s14.0,-15.5 14.0,-26.0C38.0,10.3 31.7,4.0 24.0,4.0zM24.0,23.0c-2.8,0.0 -5.0,-2.2 -5.0,-5.0s2.2,-5.0 5.0,-5.0c2.8,0.0 5.0,2.2 5.0,5.0S26.8,23.0 24.0,23.0z"/>
    <path
        android:pathData="M24.0,4.0c-7.7,0.0 -14.0,6.3 -14.0,14.0c0.0,10.5 14.0,26.0 14.0,26.0l0.0,-21.0 c-2.8,0.0 -5.0,-2.2 -5.0,-5.0s2.2,-5.0 5.0,-5.0l0.0,-9.0z"
        android:fillColor="#FFFFFFFF"/>
</vector>
+29 −0
Original line number Diff line number Diff line
<!--
    Copyright (C) 2017 The LineageOS Project
    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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="64dp"
        android:height="64dp"
        android:viewportWidth="48.0"
        android:viewportHeight="48.0">

    <path
        android:fillColor="#FFFFFFFF"
        android:pathData="M24.0,4.0c-7.7,0.0 -14.0,6.3 -14.0,14.0c0.0,10.5 14.0,26.0 14.0,26.0s14.0,-15.5 14.0,-26.0C38.0,10.3 31.7,4.0 24.0,4.0zM24.0,23.0c-2.8,0.0 -5.0,-2.2 -5.0,-5.0s2.2,-5.0 5.0,-5.0c2.8,0.0 5.0,2.2 5.0,5.0S26.8,23.0 24.0,23.0z"/>
    <path
        android:pathData="M24.0,4.0c-7.7,0.0 -14.0,6.3 -14.0,14.0c0.0,10.5 14.0,26.0 14.0,26.0l0.0,-21.0 c-2.8,0.0 -5.0,-2.2 -5.0,-5.0s2.2,-5.0 5.0,-5.0l0.0,-9.0z"
        android:fillColor="#4DFFFFFF"/>
</vector>
+64 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
     Copyright (C) 2017 The LineageOS Project
     Copyright (C) 2015-2017 The ParanoidAndroid Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/location_mode_panel"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:clipChildren="false"
    android:orientation="vertical" >

    <com.android.systemui.volume.SegmentedButtons
        android:id="@+id/location_buttons"
        android:background="@drawable/segmented_buttons_background"
        android:baselineAligned="false"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginEnd="16dp"
        android:layout_marginTop="8dp"
        android:layout_marginBottom="8dp" />

    <RelativeLayout
        android:id="@+id/location_introduction"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginEnd="16dp"
        android:paddingTop="8dp"
        android:paddingBottom="8dp"
        android:background="@drawable/zen_introduction_message_background" >

        <TextView
            android:id="@+id/location_introduction_message"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="12dp"
            android:layout_marginStart="24dp"
            android:layout_marginEnd="24dp"
            android:textDirection="locale"
            android:lineSpacingMultiplier="1.20029"
            android:textAppearance="@style/TextAppearance.QS.Introduction" />

        <View
            android:layout_width="0dp"
            android:layout_height="16dp"
            android:layout_below="@id/location_introduction_message"
            android:layout_alignParentEnd="true" />

    </RelativeLayout>
</LinearLayout>
+35 −0
Original line number Diff line number Diff line
@@ -138,4 +138,39 @@
         values/config.xml) and must be truncated.
         [CHAR LIMIT=4] -->
    <string name="status_bar_notification_info_overflow" translatable="false">\u221E</string>

    <!-- Content description of the location tile in quick settings when on, battery saving mode (not shown on the screen). [CHAR LIMIT=NONE] -->
    <string name="accessibility_quick_settings_location_battery_saving">Location reporting: battery saving mode.</string>
    <!-- Content description of the location tile in quick settings when on, sensors only mode (not shown on the screen). [CHAR LIMIT=NONE] -->
    <string name="accessibility_quick_settings_location_gps_only">Location reporting: sensors only mode.</string>
    <!-- Content description of the location tile in quick settings when on, high accuracy mode (not shown on the screen). [CHAR LIMIT=NONE] -->
    <string name="accessibility_quick_settings_location_high_accuracy">Location reporting: high accuracy mode.</string>

    <!-- QuickSettings: Location (On, low-power) [CHAR LIMIT=NONE] -->
    <string name="quick_settings_location_battery_saving_label">Battery saving</string>
    <string name="quick_settings_location_battery_saving_label_twoline">Battery\nsaving</string>
    <!-- QuickSettings: Location (On, gps-only) [CHAR LIMIT=NONE] -->
    <string name="quick_settings_location_gps_only_label">GPS only</string>
    <string name="quick_settings_location_gps_only_label_twoline">GPS only</string>
    <!-- QuickSettings: Location (On, high-accuracy) [CHAR LIMIT=NONE] -->
    <string name="quick_settings_location_high_accuracy_label">High accuracy</string>
    <string name="quick_settings_location_high_accuracy_label_twoline">High\naccuracy</string>

    <!-- QuickSettings: Location detail panel title [CHAR LIMIT=NONE] -->
    <string name="quick_settings_location_detail_title">Location</string>
    <!-- QuickSettings: Location detail panel menu title [CHAR LIMIT=NONE] -->
    <string name="quick_settings_location_detail_menu_title">Select mode:</string>
    <!-- [CHAR LIMIT=30] Location detail panel, high accuracy location mode -->
    <string name="quick_settings_location_detail_mode_high_accuracy_title">High accuracy</string>
    <!-- [CHAR LIMIT=30] Location detail panel, battery saving location mode -->
    <string name="quick_settings_location_detail_mode_battery_saving_title">Battery saving</string>
    <!-- [CHAR LIMIT=30] Location detail panel, device only location mode -->
    <string name="quick_settings_location_detail_mode_sensors_only_title">Device only</string>
    <!-- [CHAR LIMIT=130] Location detail panel, description for high accuracy mode -->
    <string name="quick_settings_location_detail_mode_high_accuracy_description">Use GPS, Wi\u2011Fi, Bluetooth, or cellular networks to determine location </string>
    <!-- [CHAR LIMIT=130] Location detail panel, description for battery saving mode -->
    <string name="quick_settings_location_detail_mode_battery_saving_description">Use Wi\u2011Fi, Bluetooth, or cellular networks to determine location</string>
    <!-- [CHAR LIMIT=130] Location detail panel, description for sensors only mode -->
    <string name="quick_settings_location_detail_mode_sensors_only_description">Use GPS to determine your location</string>

</resources>
+186 −25
Original line number Diff line number Diff line
/*
 * Copyright (C) 2014 The Android Open Source Project
 * Copyright (C) 2016 The ParanoidAndroid Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -16,23 +17,33 @@

package com.android.systemui.qs.tiles;

import android.content.Context;
import android.content.Intent;
import android.os.UserManager;

import android.provider.Settings;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.Switch;
import android.widget.TextView;

import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.systemui.R;
import com.android.systemui.qs.QSTile;
import com.android.systemui.statusbar.policy.KeyguardMonitor;
import com.android.systemui.statusbar.policy.LocationController;
import com.android.systemui.statusbar.policy.LocationController.LocationSettingsChangeCallback;
import com.android.systemui.volume.SegmentedButtons;

import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsProto.MetricsEvent;

/** Quick settings tile: Location **/
public class LocationTile extends QSTile<QSTile.BooleanState> {

    private static final Intent LOCATION_SETTINGS_INTENT
            = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);

    private final AnimationIcon mEnable =
            new AnimationIcon(R.drawable.ic_signal_location_enable_animation,
                    R.drawable.ic_signal_location_disable);
@@ -41,12 +52,15 @@ public class LocationTile extends QSTile<QSTile.BooleanState> {
                    R.drawable.ic_signal_location_enable);

    private final LocationController mController;
    private final LocationDetailAdapter mDetailAdapter;
    private final KeyguardMonitor mKeyguard;
    private final Callback mCallback = new Callback();
    private int mLastState;

    public LocationTile(Host host) {
        super(host);
        mController = host.getLocationController();
        mDetailAdapter = new LocationDetailAdapter();
        mKeyguard = host.getKeyguardMonitor();
    }

@@ -55,6 +69,11 @@ public class LocationTile extends QSTile<QSTile.BooleanState> {
        return new BooleanState();
    }

    @Override
    public DetailAdapter getDetailAdapter() {
        return mDetailAdapter;
    }

    @Override
    public void setListening(boolean listening) {
        if (listening) {
@@ -74,20 +93,20 @@ public class LocationTile extends QSTile<QSTile.BooleanState> {
    @Override
    protected void handleClick() {
        if (mKeyguard.isSecure() && mKeyguard.isShowing()) {
            mHost.startRunnableDismissingKeyguard(new Runnable() {
                @Override
                public void run() {
                    final boolean wasEnabled = (Boolean) mState.value;
            mHost.startRunnableDismissingKeyguard(() -> {
                final boolean wasEnabled = mState.value;
                mHost.openPanels();
                MetricsLogger.action(mContext, getMetricsCategory(), !wasEnabled);
                mController.setLocationEnabled(!wasEnabled);
                }
            });
            return;
        }
        final boolean wasEnabled = (Boolean) mState.value;
        final boolean wasEnabled = mState.value;
        MetricsLogger.action(mContext, getMetricsCategory(), !wasEnabled);
        mController.setLocationEnabled(!wasEnabled);
        if (!wasEnabled) {
            mController.setLocationEnabled(true);
        }
        showDetail(true);
    }

    @Override
@@ -97,28 +116,66 @@ public class LocationTile extends QSTile<QSTile.BooleanState> {

    @Override
    protected void handleUpdateState(BooleanState state, Object arg) {
        final boolean locationEnabled =  mController.isLocationEnabled();
        final int currentState = arg instanceof Integer ? (Integer) arg
                : mController.getLocationCurrentState();
        final boolean newValue = currentState != Settings.Secure.LOCATION_MODE_OFF;
        final boolean valueChanged = state.value != newValue;

        // Work around for bug 15916487: don't show location tile on top of lock screen. After the
        // bug is fixed, this should be reverted to only hiding it on secure lock screens:
        // state.visible = !(mKeyguard.isSecure() && mKeyguard.isShowing());
        state.value = locationEnabled;
        state.value = newValue;
        checkIfRestrictionEnforcedByAdminOnly(state, UserManager.DISALLOW_SHARE_LOCATION);
        if (locationEnabled) {
        state.label = mContext.getString(getStateLabelRes(currentState));
        switch (currentState) {
            case Settings.Secure.LOCATION_MODE_OFF:
                state.contentDescription = mContext.getString(
                        R.string.accessibility_quick_settings_location_off);
                state.icon = mDisable;
                break;
            case Settings.Secure.LOCATION_MODE_HIGH_ACCURACY:
                state.contentDescription = mContext.getString(
                        R.string.accessibility_quick_settings_location_high_accuracy);
                state.icon = mEnable;
            state.label = mContext.getString(R.string.quick_settings_location_label);
                break;
            case Settings.Secure.LOCATION_MODE_BATTERY_SAVING:
                state.contentDescription = mContext.getString(
                    R.string.accessibility_quick_settings_location_on);
        } else {
                        R.string.accessibility_quick_settings_location_battery_saving);
                state.icon = ResourceIcon.get(R.drawable.ic_qs_location_battery_saving);
                break;
            case Settings.Secure.LOCATION_MODE_SENSORS_ONLY:
                state.contentDescription = mContext.getString(
                        R.string.accessibility_quick_settings_location_gps_only);
                state.icon = ResourceIcon.get(R.drawable.ic_qs_location_sensors_only);
                break;
            default:
                state.icon = mDisable;
            state.label = mContext.getString(R.string.quick_settings_location_label);
                state.contentDescription = mContext.getString(
                    R.string.accessibility_quick_settings_location_off);
                        R.string.accessibility_quick_settings_location_on);
                break;
        }
        if (valueChanged) {
            fireToggleStateChanged(state.value);
        }
        state.minimalAccessibilityClassName = state.expandedAccessibilityClassName
                = Switch.class.getName();
    }

    private int getStateLabelRes(int currentState) {
        switch (currentState) {
            case Settings.Secure.LOCATION_MODE_OFF:
                return R.string.quick_settings_location_off_label;
            case Settings.Secure.LOCATION_MODE_HIGH_ACCURACY:
                return R.string.quick_settings_location_high_accuracy_label;
            case Settings.Secure.LOCATION_MODE_BATTERY_SAVING:
                return R.string.quick_settings_location_battery_saving_label;
            case Settings.Secure.LOCATION_MODE_SENSORS_ONLY:
                return R.string.quick_settings_location_gps_only_label;
            default:
                return R.string.quick_settings_location_label;
        }
    }

    @Override
    public int getMetricsCategory() {
        return MetricsEvent.QS_LOCATION;
@@ -145,4 +202,108 @@ public class LocationTile extends QSTile<QSTile.BooleanState> {
            refreshState();
        }
    };

    private class LocationDetailAdapter implements DetailAdapter {

        private SegmentedButtons mButtons;
        private ViewGroup mMessageContainer;
        private TextView mMessageText;

        @Override
        public int getMetricsCategory() {
            return MetricsEvent.QS_LOCATION_DETAIL;
        }

        @Override
        public CharSequence getTitle() {
            return mContext.getString(R.string.quick_settings_location_detail_title);
        }

        @Override
        public Boolean getToggleState() {
            return mState.value;
        }

        @Override
        public Intent getSettingsIntent() {
            return LOCATION_SETTINGS_INTENT;
        }

        @Override
        public void setToggleState(boolean state) {
            MetricsLogger.action(mContext, MetricsEvent.QS_DND_TOGGLE, state);
            if (!state) {
                mController.setLocationEnabled(state);
                showDetail(false);
            }
        }

        @Override
        public View createDetailView(Context context, View convertView, ViewGroup parent) {
            final LinearLayout details = convertView != null ? (LinearLayout) convertView
                    : (LinearLayout) LayoutInflater.from(context).inflate(
                            R.layout.location_mode_panel, parent, false);

            mLastState = mController.getLocationCurrentState();

            if (convertView == null) {
                mButtons = (SegmentedButtons) details.findViewById(R.id.location_buttons);
                mButtons.addButton(R.string.quick_settings_location_high_accuracy_label_twoline,
                        R.string.quick_settings_location_high_accuracy_label,
                        Settings.Secure.LOCATION_MODE_HIGH_ACCURACY);
                mButtons.addButton(R.string.quick_settings_location_battery_saving_label_twoline,
                        R.string.quick_settings_location_battery_saving_label,
                        Settings.Secure.LOCATION_MODE_BATTERY_SAVING);
                mButtons.addButton(R.string.quick_settings_location_gps_only_label_twoline,
                        R.string.quick_settings_location_gps_only_label,
                        Settings.Secure.LOCATION_MODE_SENSORS_ONLY);
                mButtons.setCallback(mButtonsCallback);
                mMessageContainer = (ViewGroup) details.findViewById(R.id.location_introduction);
                mMessageText = (TextView) details.findViewById(R.id.location_introduction_message);
            }

            mButtons.setSelectedValue(mLastState, false /* fromClick */);
            refresh(mLastState);

            return details;
        }

        private void refresh(int state) {
            switch (state) {
                case Settings.Secure.LOCATION_MODE_HIGH_ACCURACY:
                    mMessageText.setText(mContext.getString(R.string.quick_settings_location_detail_mode_high_accuracy_description));
                    mMessageContainer.setVisibility(View.VISIBLE);
                    break;
                case Settings.Secure.LOCATION_MODE_BATTERY_SAVING:
                    mMessageText.setText(mContext.getString(R.string.quick_settings_location_detail_mode_battery_saving_description));
                    mMessageContainer.setVisibility(View.VISIBLE);
                    break;
                case Settings.Secure.LOCATION_MODE_SENSORS_ONLY:
                    mMessageText.setText(mContext.getString(R.string.quick_settings_location_detail_mode_sensors_only_description));
                    mMessageContainer.setVisibility(View.VISIBLE);
                    break;
                default:
                    mMessageContainer.setVisibility(View.GONE);
                    break;
            }
        }

        private final SegmentedButtons.Callback mButtonsCallback = new SegmentedButtons.Callback() {
            @Override
            public void onSelected(final Object value, boolean fromClick) {
                if (value != null && mButtons.isShown()) {
                    mLastState = (Integer) value;
                    if (fromClick) {
                        MetricsLogger.action(mContext, MetricsEvent.QS_LOCATION, mLastState);
                        mController.setLocationMode(mLastState);
                        refresh(mLastState);
                    }
                }
            }

            @Override
            public void onInteraction() {
            }
        };
    }
}
Loading