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

Commit 9e450e12 authored by phweiss's avatar phweiss
Browse files

Rework Device Monitoring Dialog in Quicksettings

If a device owner is active, the layout is changed from a
standard AlertDialog with only one string to a custom dialog
that includes information on Device Owners, and VPN and Network Logging,
if enabled.

BUG: 29748723
BUG: 33126622
Test: Manual, CTS-Verifier tests will be added later

Change-Id: I2bfca9d9d02a42d9c3b17683625eda29e9369666
parent 7cd4536e
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -24,6 +24,6 @@ Copyright (C) 2016 The Android Open Source Project
  android:tint="#4DFFFFFF" >
    <path
      android:fillColor="#FFFFFFFF"
      android:pathData="M7,18v-2h6v2H7z M7,14v-2h10v2H7z M8.5,9 12,5.5 15.5,9 13,9 13,13 11,13 11,9z"/>
      android:pathData="M2,24v-4h12v4H2z M2,16v-4h20v4H2z M5,7 12,0 19,7 14,7 14,15 10,15 10,7z"/>

</vector>
+117 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
     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.
-->

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/scrollView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:clipToPadding="false">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingTop="?android:attr/dialogPreferredPadding"
        android:paddingRight="?android:attr/dialogPreferredPadding"
        android:paddingLeft="?android:attr/dialogPreferredPadding"
        android:paddingBottom="?android:attr/dialogPreferredPadding"
        android:orientation="vertical">
        <TextView
            android:id="@+id/device_owner_warning"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            style="@android:style/TextAppearance.Material.Subhead"
            android:textColor="?android:attr/textColorPrimaryInverse"
        />
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <ImageView
                android:id="@+id/vpn_icon"
                android:layout_width="@dimen/qs_footer_dialog_icon_size"
                android:layout_height="wrap_content"
                android:paddingTop="?android:attr/dialogPreferredPadding"
                android:layout_marginStart="@dimen/qs_footer_dialog_icon_margin"
                android:layout_marginEnd="@dimen/qs_footer_dialog_icon_margin"
                android:scaleType="fitCenter"
                android:src="@drawable/ic_qs_vpn"
                android:tint="?android:attr/textColorPrimaryInverse"
                android:adjustViewBounds="true"/>
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">
                <TextView
                    android:id="@+id/vpn_subtitle"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:paddingTop="?android:attr/dialogPreferredPadding"
                    android:text="@string/monitoring_subtitle_vpn"
                    style="@android:style/TextAppearance.Material.Title"
                    android:textColor="?android:attr/textColorPrimaryInverse"
                />
                <TextView
                    android:id="@+id/vpn_warning"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@null"
                    style="@android:style/TextAppearance.Material.Subhead"
                    android:textColor="?android:attr/textColorPrimaryInverse"
                />
            </LinearLayout>
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <ImageView
                android:id="@+id/network_logging_icon"
                android:layout_width="@dimen/qs_footer_dialog_icon_size"
                android:layout_height="wrap_content"
                android:paddingTop="?android:attr/dialogPreferredPadding"
                android:layout_marginStart="@dimen/qs_footer_dialog_icon_margin"
                android:layout_marginEnd="@dimen/qs_footer_dialog_icon_margin"
                android:scaleType="fitCenter"
                android:src="@drawable/ic_qs_network_logging"
                android:tint="?android:attr/textColorPrimaryInverse"
                android:alpha="@dimen/qs_footer_dialog_network_logging_icon_alpha"
                android:adjustViewBounds="true"/>
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">
                <TextView
                    android:id="@+id/network_logging_subtitle"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:paddingTop="?android:attr/dialogPreferredPadding"
                    android:text="@string/monitoring_subtitle_network_logging"
                    style="@android:style/TextAppearance.Material.Title"
                    android:textColor="?android:attr/textColorPrimaryInverse"
                />
                <TextView
                    android:id="@+id/network_logging_warning"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/monitoring_description_network_logging"
                    style="@android:style/TextAppearance.Material.Subhead"
                    android:textColor="?android:attr/textColorPrimaryInverse"
                />
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>
</ScrollView>
+7 −0
Original line number Diff line number Diff line
@@ -258,6 +258,13 @@
    <!-- How far the expanded QS panel peeks from the header in collapsed state. -->
    <dimen name="qs_peek_height">0dp</dimen>

    <!-- How large the icons in the quick settings footer dialog are -->
    <dimen name="qs_footer_dialog_icon_size">24sp</dimen>
    <!-- Left and right margin of the icons -->
    <dimen name="qs_footer_dialog_icon_margin">8sp</dimen>
    <!-- Alpha value of network logging icon -->
    <dimen name="qs_footer_dialog_network_logging_icon_alpha">0.3</dimen>

    <!-- Zen mode panel: condition item button padding -->
    <dimen name="zen_mode_condition_detail_button_padding">8dp</dimen>

+20 −3
Original line number Diff line number Diff line
@@ -1010,6 +1010,13 @@
    <!-- Monitoring dialog title for normal devices  [CHAR LIMIT=35]-->
    <string name="monitoring_title">Network monitoring</string>

    <!-- STOPSHIP Monitoring strings still need to be finalized and approved -->
    <!-- Monitoring dialog subtitle for the section describing VPN [CHAR LIMIT=TODO]-->
    <string name="monitoring_subtitle_vpn">VPN</string>

    <!-- Monitoring dialog subtitle for the section describing network logging [CHAR LIMIT=TODO]-->
    <string name="monitoring_subtitle_network_logging">Network Logging</string>

    <!-- Monitoring dialog disable vpn button [CHAR LIMIT=30] -->
    <string name="disable_vpn">Disable VPN</string>

@@ -1025,15 +1032,25 @@
    <!-- Monitoring dialog: Part of text body explaining what a Device Owner app can do [CHAR LIMIT=130] -->
    <string name="monitoring_description_do_body">Your administrator can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.</string>

    <!-- Monitoring dialog: Part of text body explaining that a VPN is connected and what it can do, for devices managed by a Device Owner app [CHAR LIMIT=130] -->
    <string name="monitoring_description_do_body_vpn">You\'re connected to <xliff:g id="vpn_app">%1$s</xliff:g>, which can monitor your network activity, including emails, apps, and websites.</string>

    <!-- Monitoring dialog: Space that separates the body text and the "learn more" link that follows it. [CHAR LIMIT=5] -->
    <string name="monitoring_description_do_learn_more_separator">" "</string>

    <!-- Monitoring dialog: Link to learn more about what a Device Owner app can do [CHAR LIMIT=55] -->
    <string name="monitoring_description_do_learn_more">Learn more</string>

    <!-- Monitoring dialog: Part of text body explaining that a VPN is connected and what it can do, for devices managed by a Device Owner app [CHAR LIMIT=130] -->
    <string name="monitoring_description_do_body_vpn">You\'re connected to <xliff:g id="vpn_app">%1$s</xliff:g>, which can monitor your network activity, including emails, apps, and websites.</string>

    <!-- Monitoring dialog: Space that separates the VPN body text and the "Open VPN Settings" link that follows it. [CHAR LIMIT=5] -->
    <string name="monitoring_description_vpn_settings_separator">" "</string>

    <!-- Monitoring dialog: Link to open the VPN settings page [CHAR LIMIT=TODO] -->
    <string name="monitoring_description_vpn_settings">Open VPN Settings</string>

    <!-- Monitoring dialog: Network logging text [CHAR LIMIT=TODO] -->
    <string name="monitoring_description_network_logging">Your admin has turned on network logging, which monitors traffic on your device.\n\nFor more information contact your admin.</string>


    <!-- Monitoring dialog VPN text [CHAR LIMIT=400] -->
    <string name="monitoring_description_vpn">You gave an app permission to set up a VPN connection.\n\nThis app can monitor your device and network activity, including emails, apps, and websites.</string>

+50 −20
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import android.text.style.ClickableSpan;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.ImageView;
@@ -175,6 +176,7 @@ public class QSFooter implements OnClickListener, DialogInterface.OnClickListene
    private void createDialog() {
        final String deviceOwnerPackage = mSecurityController.getDeviceOwnerName();
        final String profileOwnerPackage = mSecurityController.getProfileOwnerName();
        final boolean isNetworkLoggingEnabled = mSecurityController.isNetworkLoggingEnabled();
        final String primaryVpn = mSecurityController.getPrimaryVpnName();
        final String profileVpn = mSecurityController.getProfileVpnName();
        final CharSequence deviceOwnerOrganization =
@@ -186,24 +188,47 @@ public class QSFooter implements OnClickListener, DialogInterface.OnClickListene
        if (!isBranded) {
            mDialog.setTitle(getTitle(deviceOwnerPackage));
        }
        mDialog.setMessage(getMessage(deviceOwnerPackage, profileOwnerPackage, primaryVpn,
                profileVpn, deviceOwnerOrganization, hasProfileOwner, isBranded));
        CharSequence msg = getMessage(deviceOwnerPackage, profileOwnerPackage, primaryVpn,
                profileVpn, deviceOwnerOrganization, hasProfileOwner, isBranded);
        if (deviceOwnerPackage == null) {
            mDialog.setMessage(msg);
        } else {
            View dialogView = LayoutInflater.from(mContext)
                   .inflate(R.layout.quick_settings_footer_dialog, null, false);
            mDialog.setView(dialogView);
            TextView deviceOwnerWarning =
                    (TextView) dialogView.findViewById(R.id.device_owner_warning);
            deviceOwnerWarning.setText(msg);
            // Make the link "learn more" clickable.
            deviceOwnerWarning.setMovementMethod(new LinkMovementMethod());
            if (primaryVpn == null) {
                dialogView.findViewById(R.id.vpn_icon).setVisibility(View.GONE);
                dialogView.findViewById(R.id.vpn_subtitle).setVisibility(View.GONE);
                dialogView.findViewById(R.id.vpn_warning).setVisibility(View.GONE);
            } else {
                final SpannableStringBuilder message = new SpannableStringBuilder();
                message.append(mContext.getString(R.string.monitoring_description_do_body_vpn,
                        primaryVpn));
                message.append(mContext.getString(
                        R.string.monitoring_description_vpn_settings_separator));
                message.append(mContext.getString(R.string.monitoring_description_vpn_settings),
                        new VpnSpan(), 0);

        mDialog.setButton(DialogInterface.BUTTON_POSITIVE, getPositiveButton(isBranded), this);
        if (mSecurityController.isVpnEnabled() && !mSecurityController.isVpnRestricted()) {
            mDialog.setButton(DialogInterface.BUTTON_NEGATIVE, getSettingsButton(), this);
                TextView vpnWarning = (TextView) dialogView.findViewById(R.id.vpn_warning);
                vpnWarning.setText(message);
                // Make the link "Open VPN Settings" clickable.
                vpnWarning.setMovementMethod(new LinkMovementMethod());
            }
            if (!isNetworkLoggingEnabled) {
                dialogView.findViewById(R.id.network_logging_icon).setVisibility(View.GONE);
                dialogView.findViewById(R.id.network_logging_subtitle).setVisibility(View.GONE);
                dialogView.findViewById(R.id.network_logging_warning).setVisibility(View.GONE);
            }
        }

        // Make the link "learn more" clickable.
        // TODO: Reaching into SystemUIDialog's internal View hierarchy is ugly and error-prone.
        // This is a temporary solution. b/33126622 will introduce a custom View hierarchy for this
        // dialog, allowing us to set the movement method on the appropriate View without any
        // knowledge of SystemUIDialog's internals.
        mDialog.create();
        ((TextView) mDialog.getWindow().findViewById(com.android.internal.R.id.message))
                .setMovementMethod(new LinkMovementMethod());

        mDialog.setButton(DialogInterface.BUTTON_POSITIVE, getPositiveButton(isBranded), this);
        mDialog.show();
        mDialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
    }

    private String getSettingsButton() {
@@ -229,11 +254,6 @@ public class QSFooter implements OnClickListener, DialogInterface.OnClickListene
            }
            message.append("\n\n");
            message.append(mContext.getString(R.string.monitoring_description_do_body));
            if (primaryVpn != null) {
                message.append("\n\n");
                message.append(mContext.getString(R.string.monitoring_description_do_body_vpn,
                        primaryVpn));
            }
            message.append(mContext.getString(
                    R.string.monitoring_description_do_learn_more_separator));
            message.append(mContext.getString(R.string.monitoring_description_do_learn_more),
@@ -340,4 +360,14 @@ public class QSFooter implements OnClickListener, DialogInterface.OnClickListene
            return object instanceof EnterprisePrivacySpan;
        }
    }

    protected class VpnSpan extends ClickableSpan {
        @Override
        public void onClick(View widget) {
            final Intent intent = new Intent(Settings.ACTION_VPN_SETTINGS);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
            mDialog.dismiss();
            mContext.startActivity(intent);
        }
    }
}
Loading