Merge "Merge bool.xml and config.xml into one file."
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index a007f99..90aa55f 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1236,10 +1236,6 @@
                 android:configChanges="orientation|keyboardHidden|screenSize"
                 android:parentActivityName="Settings">
             <intent-filter>
-                <action android:name="android.settings.PRIVACY_SETTINGS" />
-                <category android:name="android.intent.category.DEFAULT" />
-            </intent-filter>
-            <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.DEFAULT" />
                 <category android:name="android.intent.category.VOICE_LAUNCH" />
@@ -1250,6 +1246,17 @@
                 android:value="true" />
         </activity>
 
+        <activity android:name="Settings$PrivacyDashboardActivity"
+                  android:label="@string/privacy_dashboard_title"
+                  android:icon="@drawable/ic_settings_privacy">
+            <intent-filter>
+                <action android:name="android.settings.PRIVACY_SETTINGS" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
+                       android:value="com.android.settings.privacy.PrivacyDashboardFragment" />
+        </activity>
+
         <activity android:name="SetFullBackupPassword"
                   android:label="@string/local_backup_password_title"
                   android:exported="false" />
diff --git a/res/layout/preference_balance_slider.xml b/res/layout/preference_balance_slider.xml
new file mode 100644
index 0000000..32010c3
--- /dev/null
+++ b/res/layout/preference_balance_slider.xml
@@ -0,0 +1,109 @@
+<?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.
+-->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:minHeight="?android:attr/listPreferredItemHeightSmall"
+    android:gravity="center_vertical"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+    android:clickable="false"
+    android:orientation="horizontal">
+
+    <LinearLayout
+        android:id="@+id/icon_frame"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:minWidth="56dp"
+        android:gravity="start|center_vertical"
+        android:orientation="horizontal"
+        android:paddingEnd="12dp"
+        android:paddingTop="4dp"
+        android:paddingBottom="4dp">
+        <com.android.internal.widget.PreferenceImageView
+            android:id="@android:id/icon"
+            android:layout_width="24dp"
+            android:layout_height="24dp"/>
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        android:layout_marginTop="8dp"
+        android:layout_marginBottom="8dp">
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content">
+            <TextView
+                android:id="@android:id/title"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:singleLine="true"
+                android:textAppearance="@*android:style/TextAppearance.Material.Subhead"
+                android:textColor="?android:attr/textColorPrimary"
+                android:ellipsize="marquee"
+                android:fadingEdge="horizontal"/>
+            <LinearLayout
+                android:id="@android:id/widget_frame"
+                android:layout_width="wrap_content"
+                android:layout_height="match_parent"
+                android:gravity="center_vertical"
+                android:orientation="vertical"/>
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="vertical">
+
+            <com.android.settings.accessibility.BalanceSeekBar
+                android:id="@*android:id/seekbar"
+                android:layout_gravity="center_vertical"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"/>
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_vertical"
+                android:orientation="horizontal">
+                <TextView
+                    android:id="@+id/left_text"
+                    android:text="@string/accessibility_toggle_master_balance_left_label"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:maxLines="1"
+                    android:textAlignment="viewStart" />
+                <TextView
+                    android:id="@+id/right_text"
+                    android:text="@string/accessibility_toggle_master_balance_right_label"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:maxLines="1"
+                    android:textAlignment="viewEnd" />
+
+            </LinearLayout>
+        </LinearLayout>
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 0a35188..d42f073 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -38,6 +38,9 @@
 
     <dimen name="volume_seekbar_side_margin">8dip</dimen>
 
+    <dimen name="balance_seekbar_center_marker_height">14dp</dimen>
+    <dimen name="balance_seekbar_center_marker_width">1dp</dimen>
+
     <dimen name="crypt_clock_size">100sp</dimen>
 
     <dimen name="divider_height">3dip</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index ae0b8f0..08c46d5 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -4717,6 +4717,12 @@
     <string name="accessibility_toggle_master_mono_title">Mono audio</string>
     <!-- Summary for the accessibility preference for master mono. [CHAR LIMIT=50] -->
     <string name="accessibility_toggle_master_mono_summary">Combine channels when playing audio</string>
+    <!-- Title for the accessibility preference for master balance. [CHAR LIMIT=35] -->
+    <string name="accessibility_toggle_master_balance_title">Audio balance</string>
+    <!-- 'Left' balance text for the accessibility preference for master balance. [CHAR LIMIT=20] -->
+    <string name="accessibility_toggle_master_balance_left_label">Left</string>
+    <!-- 'Right' balance text for the accessibility preference for master balance. [CHAR LIMIT=20] -->
+    <string name="accessibility_toggle_master_balance_right_label">Right</string>
 
     <!-- Option heading to leave the timeout requirement for accessibility users at its default level. [CHAR LIMIT=35] -->
     <string name="accessibility_timeout_default">Default</string>
@@ -5851,9 +5857,9 @@
     <!-- Summary for whether to enable SMS access restriction [CHAR LIMIT=NONE]-->
     <string name="sms_access_restriction_enabled_summary">Only default phone and messaging apps have SMS &amp; call log permissions</string>
     <!-- Title for the new device identifier access restrictions [CHAR LIMIT=50]-->
-    <string name="device_identifier_access_restrictions_title">Enable device identifier restrictions</string>
+    <string name="device_identifier_access_restrictions_title">Disable device identifier restrictions</string>
     <!-- Summary for the new device identifier access restrictions [CHAR LIMIT=NONE]-->
-    <string name="device_identifier_access_restrictions_summary">Enable the new access restrictions for device identifiers.</string>
+    <string name="device_identifier_access_restrictions_summary">Disable the new access restrictions for device identifiers</string>
 
 
     <!-- Message when there are no available trust agents to display -->
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 6d153e1..935bbf2 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -419,7 +419,7 @@
         <item name="android:layout_marginBottom">@dimen/homepage_card_vertical_margin</item>
         <item name="android:layout_marginStart">@dimen/homepage_card_side_margin</item>
         <item name="android:layout_marginEnd">@dimen/homepage_card_side_margin</item>
-        <item name="cardCornerRadius">8dp</item>
+        <item name="cardCornerRadius">@*android:dimen/config_dialogCornerRadius</item>
         <item name="cardElevation">0dp</item>
         <item name="strokeColor">@color/homepage_card_stroke_color</item>
         <item name="strokeWidth">1dp</item>
diff --git a/res/xml/accessibility_settings.xml b/res/xml/accessibility_settings.xml
index cc07ce1..9cb73a2 100644
--- a/res/xml/accessibility_settings.xml
+++ b/res/xml/accessibility_settings.xml
@@ -130,6 +130,10 @@
                 android:summary="@string/accessibility_toggle_master_mono_summary"
                 android:persistent="false"/>
 
+        <com.android.settings.accessibility.BalanceSeekBarPreference
+                android:key="seekbar_master_balance"
+                android:title="@string/accessibility_toggle_master_balance_title" />
+
         <Preference
             android:key="hearing_aid_preference"
             android:summary="@string/accessibility_hearingaid_not_connected_summary"
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 8cff5f1..e7f543a 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -71,6 +71,7 @@
     public static class AppUsageAccessSettingsActivity extends SettingsActivity { /* empty */ }
     public static class LocationSettingsActivity extends SettingsActivity { /* empty */ }
     public static class ScanningSettingsActivity extends SettingsActivity { /* empty */ }
+    public static class PrivacyDashboardActivity extends SettingsActivity { /* empty */ }
     public static class PrivacySettingsActivity extends SettingsActivity { /* empty */ }
     public static class FactoryResetActivity extends SettingsActivity { /* empty */ }
     public static class RunningServicesActivity extends SettingsActivity { /* empty */ }
diff --git a/src/com/android/settings/accessibility/BalanceSeekBar.java b/src/com/android/settings/accessibility/BalanceSeekBar.java
new file mode 100644
index 0000000..e18a593
--- /dev/null
+++ b/src/com/android/settings/accessibility/BalanceSeekBar.java
@@ -0,0 +1,152 @@
+/*
+ * 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.settings.accessibility;
+
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.AttributeSet;
+import android.widget.SeekBar;
+
+import com.android.settings.R;
+
+/**
+ * A custom seekbar for the balance setting.
+ *
+ * Adds a center line indicator between left and right, which snaps to if close.
+ * Updates Settings.System for balance on progress changed.
+ */
+public class BalanceSeekBar extends SeekBar {
+    private static final String TAG = "BalanceSeekBar";
+    private final Context mContext;
+    private final Object mListenerLock = new Object();
+    private OnSeekBarChangeListener mOnSeekBarChangeListener;
+    private final OnSeekBarChangeListener mProxySeekBarListener = new OnSeekBarChangeListener() {
+        @Override
+        public void onStopTrackingTouch(SeekBar seekBar) {
+            synchronized(mListenerLock) {
+                if (mOnSeekBarChangeListener != null) {
+                    mOnSeekBarChangeListener.onStopTrackingTouch(seekBar);
+                }
+            }
+        }
+
+        @Override
+        public void onStartTrackingTouch(SeekBar seekBar) {
+            synchronized(mListenerLock) {
+                if (mOnSeekBarChangeListener != null) {
+                    mOnSeekBarChangeListener.onStartTrackingTouch(seekBar);
+                }
+            }
+        }
+
+        @Override
+        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+            if (fromUser) {
+                // Snap to centre when within the specified threshold
+                if (progress != mCenter
+                        && progress > mCenter - mSnapThreshold
+                        && progress < mCenter + mSnapThreshold) {
+                    progress = mCenter;
+                    seekBar.setProgress(progress); // direct update (fromUser becomes false)
+                }
+                final float balance = (progress - mCenter) * 0.01f;
+                Settings.System.putFloatForUser(mContext.getContentResolver(),
+                        Settings.System.MASTER_BALANCE, balance, UserHandle.USER_CURRENT);
+            }
+            // If fromUser is false, the call is a set from the framework on creation or on
+            // internal update. The progress may be zero, ignore (don't change system settings).
+
+            // after adjusting the seekbar, notify downstream listener.
+            // note that progress may have been adjusted in the code above to mCenter.
+            synchronized(mListenerLock) {
+                if (mOnSeekBarChangeListener != null) {
+                    mOnSeekBarChangeListener.onProgressChanged(seekBar, progress, fromUser);
+                }
+            }
+        }
+    };
+
+    // Percentage of max to be used as a snap to threshold
+    private static final float SNAP_TO_PERCENTAGE = 0.03f;
+    private final Paint mCenterMarkerPaint;
+    private final Rect mCenterMarkerRect;
+    // changed in setMax()
+    private float mSnapThreshold;
+    private int mCenter;
+
+    public BalanceSeekBar(Context context, AttributeSet attrs) {
+        this(context, attrs, com.android.internal.R.attr.seekBarStyle);
+    }
+
+    public BalanceSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0 /* defStyleRes */);
+    }
+
+    public BalanceSeekBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+        mContext = context;
+        Resources res = getResources();
+        mCenterMarkerRect = new Rect(0 /* left */, 0 /* top */,
+                res.getDimensionPixelSize(R.dimen.balance_seekbar_center_marker_width),
+                res.getDimensionPixelSize(R.dimen.balance_seekbar_center_marker_height));
+        mCenterMarkerPaint = new Paint();
+        // TODO use a more suitable colour?
+        mCenterMarkerPaint.setColor(Color.BLACK);
+        mCenterMarkerPaint.setStyle(Paint.Style.FILL);
+        // Remove the progress colour
+        setProgressTintList(ColorStateList.valueOf(Color.TRANSPARENT));
+
+        super.setOnSeekBarChangeListener(mProxySeekBarListener);
+    }
+
+    @Override
+    public void setOnSeekBarChangeListener(OnSeekBarChangeListener listener) {
+        synchronized(mListenerLock) {
+            mOnSeekBarChangeListener = listener;
+        }
+    }
+
+    // Note: the superclass AbsSeekBar.setMax is synchronized.
+    @Override
+    public synchronized void setMax(int max) {
+        super.setMax(max);
+        // update snap to threshold
+        mCenter = max / 2;
+        mSnapThreshold = max * SNAP_TO_PERCENTAGE;
+    }
+
+    // Note: the superclass AbsSeekBar.onDraw is synchronized.
+    @Override
+    protected synchronized void onDraw(Canvas canvas) {
+        // Draw a vertical line at 50% that represents centred balance
+        int seekBarCenter = (canvas.getHeight() - getPaddingBottom()) / 2;
+        canvas.save();
+        canvas.translate((canvas.getWidth() - mCenterMarkerRect.right) / 2,
+                seekBarCenter - (mCenterMarkerRect.bottom / 2));
+        canvas.drawRect(mCenterMarkerRect, mCenterMarkerPaint);
+        canvas.restore();
+        super.onDraw(canvas);
+    }
+}
+
diff --git a/src/com/android/settings/accessibility/BalanceSeekBarPreference.java b/src/com/android/settings/accessibility/BalanceSeekBarPreference.java
new file mode 100644
index 0000000..a40282c
--- /dev/null
+++ b/src/com/android/settings/accessibility/BalanceSeekBarPreference.java
@@ -0,0 +1,70 @@
+/*
+ * 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.settings.accessibility;
+
+import android.content.Context;
+import android.media.AudioSystem;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.SeekBar;
+
+import androidx.core.content.res.TypedArrayUtils;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceViewHolder;
+
+import com.android.settings.R;
+import com.android.settings.widget.SeekBarPreference;
+
+/** A slider preference that directly controls audio balance **/
+public class BalanceSeekBarPreference extends SeekBarPreference {
+    private static final String TAG = "BalanceSeekBarPreference";
+    private final Context mContext;
+    private BalanceSeekBar mSeekBar;
+    private ImageView mIconView;
+
+    public BalanceSeekBarPreference(Context context, AttributeSet attrs) {
+        super(context, attrs, TypedArrayUtils.getAttr(context,
+                R.attr.preferenceStyle,
+                android.R.attr.preferenceStyle));
+        mContext = context;
+        setLayoutResource(R.layout.preference_balance_slider);
+    }
+
+    @Override
+    public void onBindViewHolder(PreferenceViewHolder view) {
+        super.onBindViewHolder(view);
+        mSeekBar = (BalanceSeekBar) view.findViewById(com.android.internal.R.id.seekbar);
+        mIconView = (ImageView) view.findViewById(com.android.internal.R.id.icon);
+        init();
+    }
+
+    private void init() {
+        if (mSeekBar == null) {
+            return;
+        }
+        final float balance = Settings.System.getFloatForUser(
+                mContext.getContentResolver(), Settings.System.MASTER_BALANCE,
+                0.f /* default */, UserHandle.USER_CURRENT);
+        // Rescale balance to range 0-200 centered at 100.
+        mSeekBar.setMax(200);
+        mSeekBar.setProgress((int)(balance * 100.f) + 100);
+        mSeekBar.setEnabled(isEnabled());
+    }
+}
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index bb292a1..fb3d0c5 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -274,6 +274,7 @@
             Settings.StorageDashboardActivity.class.getName(),
             Settings.PowerUsageSummaryActivity.class.getName(),
             Settings.AccountDashboardActivity.class.getName(),
+            Settings.PrivacySettingsActivity.class.getName(),
             Settings.SecurityDashboardActivity.class.getName(),
             Settings.AccessibilitySettingsActivity.class.getName(),
             Settings.SystemDashboardActivity.class.getName(),
diff --git a/src/com/android/settings/development/DeviceIdentifierAccessRestrictionsPreferenceController.java b/src/com/android/settings/development/DeviceIdentifierAccessRestrictionsPreferenceController.java
index 1fdbe77..05ac8c7 100644
--- a/src/com/android/settings/development/DeviceIdentifierAccessRestrictionsPreferenceController.java
+++ b/src/com/android/settings/development/DeviceIdentifierAccessRestrictionsPreferenceController.java
@@ -50,12 +50,12 @@
     private void writeSetting(boolean isEnabled) {
         DeviceConfig.setProperty(DeviceConfig.Privacy.NAMESPACE,
                 DeviceConfig.Privacy.PROPERTY_DEVICE_IDENTIFIER_ACCESS_RESTRICTIONS_DISABLED,
-                String.valueOf(!isEnabled), false);
+                String.valueOf(isEnabled), false);
     }
 
     @Override
     public void updateState(Preference preference) {
-        boolean isEnabled = !Boolean.parseBoolean(
+        boolean isEnabled = Boolean.parseBoolean(
                 DeviceConfig.getProperty(DeviceConfig.Privacy.NAMESPACE,
                         DeviceConfig.Privacy.PROPERTY_DEVICE_IDENTIFIER_ACCESS_RESTRICTIONS_DISABLED));
         ((SwitchPreference) mPreference).setChecked(isEnabled);
@@ -64,7 +64,7 @@
     @Override
     protected void onDeveloperOptionsSwitchDisabled() {
         super.onDeveloperOptionsSwitchDisabled();
-        writeSetting(true);
+        writeSetting(false);
         ((SwitchPreference) mPreference).setChecked(true);
     }
 }
diff --git a/tests/robotests/src/com/android/settings/backup/BackupSettingsHelperTest.java b/tests/robotests/src/com/android/settings/backup/BackupSettingsHelperTest.java
index ee8912a..5587783 100644
--- a/tests/robotests/src/com/android/settings/backup/BackupSettingsHelperTest.java
+++ b/tests/robotests/src/com/android/settings/backup/BackupSettingsHelperTest.java
@@ -31,16 +31,13 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
-import android.content.pm.UserInfo;
 import android.content.res.Resources;
 import android.os.IBinder;
 import android.os.RemoteException;
-
 import android.os.UserHandle;
-import android.os.UserManager;
+
 import com.android.settings.R;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -57,8 +54,6 @@
 @RunWith(RobolectricTestRunner.class)
 @Config(shadows = BackupSettingsHelperTest.ShadowBackupManagerStub.class)
 public class BackupSettingsHelperTest {
-    private static final String DEFAULT_SETTINGS_CLASSNAME =
-            "com.android.settings.Settings$PrivacySettingsActivity";
 
     private static final int DEFAULT_SUMMARY_RESOURCE =
             R.string.backup_configure_account_default_summary;
@@ -295,16 +290,6 @@
     }
 
     @Test
-    public void testGetIntentForBackupSettings_WithoutIntentFromTransport() throws Exception {
-        when(mBackupManager.getDataManagementIntent(anyString())).thenReturn(null);
-
-        Intent backupIntent = mBackupSettingsHelper.getIntentForBackupSettings();
-
-        assertThat(backupIntent.getComponent().getClassName())
-            .isEqualTo(DEFAULT_SETTINGS_CLASSNAME);
-    }
-
-    @Test
     public void testGetLabelForBackupSettings_WithLabelFromTransport() throws Exception {
         String label = "test_label";