diff --git a/res/layout/layout_color_selector.xml b/res/layout/layout_color_selector.xml
index c366add00ec..a6b9cc89688 100644
--- a/res/layout/layout_color_selector.xml
+++ b/res/layout/layout_color_selector.xml
@@ -14,161 +14,167 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
-
+ android:padding="20dp"
+ android:clipToPadding="false"
+ android:scrollbarStyle="outsideOverlay">
-
-
-
-
+
+ android:layout_marginBottom="10dp"
+ android:orientation="horizontal">
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+ android:layout_marginBottom="10dp"
+ android:orientation="horizontal">
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+ android:layout_marginBottom="10dp"
+ android:orientation="horizontal">
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
diff --git a/res/layout/layout_color_selector_dialog.xml b/res/layout/layout_color_selector_dialog.xml
index 70d4509f07e..e107689ae6a 100644
--- a/res/layout/layout_color_selector_dialog.xml
+++ b/res/layout/layout_color_selector_dialog.xml
@@ -17,16 +17,12 @@
+ android:gravity="center_horizontal"
+ android:orientation="vertical">
+ android:layout_height="wrap_content"/>
\ No newline at end of file
diff --git a/src/com/android/settings/connecteddevice/stylus/StylusDevicesController.java b/src/com/android/settings/connecteddevice/stylus/StylusDevicesController.java
index ec9f4c6eb51..0a0e2081a8f 100644
--- a/src/com/android/settings/connecteddevice/stylus/StylusDevicesController.java
+++ b/src/com/android/settings/connecteddevice/stylus/StylusDevicesController.java
@@ -124,7 +124,7 @@ public class StylusDevicesController extends AbstractPreferenceController implem
try {
ApplicationInfo ai = pm.getApplicationInfo(packageName,
PackageManager.ApplicationInfoFlags.of(0));
- appName = ai == null ? packageName : pm.getApplicationLabel(ai).toString();
+ appName = ai == null ? "" : pm.getApplicationLabel(ai).toString();
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "Notes role package not found.");
}
diff --git a/src/com/android/settings/display/ScreenResolutionFragment.java b/src/com/android/settings/display/ScreenResolutionFragment.java
index de7d25fefb9..daf1793f11f 100644
--- a/src/com/android/settings/display/ScreenResolutionFragment.java
+++ b/src/com/android/settings/display/ScreenResolutionFragment.java
@@ -369,6 +369,12 @@ public class ScreenResolutionFragment extends RadioButtonPickerFragment {
private void restoreDensity() {
final DisplayDensityUtils density = new DisplayDensityUtils(mContext);
+ /* If current density is the same as a default density of other resolutions,
+ * then mCurrentIndex may be out of boundary.
+ */
+ if (density.getDefaultDisplayDensityValues().length <= mCurrentIndex) {
+ mCurrentIndex = density.getCurrentIndexForDefaultDisplay();
+ }
if (density.getDefaultDisplayDensityValues()[mCurrentIndex]
!= density.getDefaultDensityForDefaultDisplay()) {
density.setForcedDisplayDensity(mCurrentIndex);
diff --git a/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java b/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java
index 0b0e2430c90..c06e7f023d9 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java
@@ -128,6 +128,11 @@ public interface PowerUsageFeatureProvider {
*/
boolean delayHourlyJobWhenBooting();
+ /**
+ * Insert device usage data for anomaly detection
+ */
+ void insertSettingsData(Context context);
+
/**
* Gets an intent for one time bypass charge limited to resume charging.
*/
diff --git a/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java b/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java
index 1d0ba18b40f..89d793a9e92 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java
@@ -160,6 +160,9 @@ public class PowerUsageFeatureProviderImpl implements PowerUsageFeatureProvider
return true;
}
+ @Override
+ public void insertSettingsData(Context context) {}
+
@Override
public Set getOthersSystemComponentSet() {
return new ArraySet<>();
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java
index 0fae92d575c..891e5e0b0ec 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java
@@ -18,6 +18,7 @@ package com.android.settings.fuelgauge.batteryusage;
import static com.android.settings.Utils.formatPercentage;
import static com.android.settings.fuelgauge.batteryusage.BatteryChartViewModel.AxisLabelPosition.BETWEEN_TRAPEZOIDS;
+import static java.lang.Math.abs;
import static java.lang.Math.round;
import static java.util.Objects.requireNonNull;
@@ -74,6 +75,8 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick
private final Rect[] mPercentageBounds = new Rect[]{new Rect(), new Rect(), new Rect()};
private final List mAxisLabelsBounds = new ArrayList<>();
private final Set mLabelDrawnIndexes = new ArraySet<>();
+ private final int mLayoutDirection =
+ getContext().getResources().getConfiguration().getLayoutDirection();
private BatteryChartViewModel mViewModel;
private int mHoveredIndex = BatteryChartViewModel.SELECTED_INDEX_INVALID;
@@ -159,7 +162,12 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick
}
// Updates the indent configurations.
mIndent.top = mPercentageBounds[0].height();
- mIndent.right = mPercentageBounds[0].width() + mTextPadding;
+ final int textWidth = mPercentageBounds[0].width() + mTextPadding;
+ if (isRTL()) {
+ mIndent.left = textWidth;
+ } else {
+ mIndent.right = textWidth;
+ }
if (mViewModel != null) {
int maxTop = 0;
@@ -334,7 +342,7 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick
}
private void drawHorizontalDividers(Canvas canvas) {
- final int width = getWidth() - mIndent.right;
+ final int width = getWidth() - abs(mIndent.width());
final int height = getHeight() - mIndent.top - mIndent.bottom;
final float topOffsetY = mIndent.top + mDividerWidth * .5f;
final float bottomOffsetY = mIndent.top + (height - mDividerHeight - mDividerWidth * .5f);
@@ -347,7 +355,8 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick
// Draws 5 divider lines.
for (int index = 0; index < HORIZONTAL_DIVIDER_COUNT; index++) {
float offsetY = topOffsetY + dividerOffsetUnit * index;
- canvas.drawLine(0, offsetY, width, offsetY, mDividerPaint);
+ canvas.drawLine(mIndent.left, offsetY,
+ mIndent.left + width, offsetY, mDividerPaint);
// Draws percentage text only for 100% / 50% / 0%
if (index % 2 == 0) {
@@ -362,14 +371,14 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick
mTextPaint.setColor(mDefaultTextColor);
canvas.drawText(
mPercentages[index],
- getWidth(),
+ isRTL() ? mIndent.left - mTextPadding : getWidth(),
offsetY + mPercentageBounds[index].height() * .5f,
mTextPaint);
}
}
private void drawVerticalDividers(Canvas canvas) {
- final int width = getWidth() - mIndent.right;
+ final int width = getWidth() - abs(mIndent.width());
final int dividerCount = mTrapezoidSlots.length + 1;
final float dividerSpace = dividerCount * mDividerWidth;
final float unitWidth = (width - dividerSpace) / (float) mTrapezoidSlots.length;
@@ -384,7 +393,7 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick
case CENTER_OF_TRAPEZOIDS:
axisLabelDisplayAreas = getAxisLabelDisplayAreas(
/* size= */ mViewModel.size() - 1,
- /* baselineX= */ mDividerWidth + unitWidth * .5f,
+ /* baselineX= */ mIndent.left + mDividerWidth + unitWidth * .5f,
/* offsetX= */ mDividerWidth + unitWidth,
baselineY,
/* shiftFirstAndLast= */ false);
@@ -393,7 +402,7 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick
default:
axisLabelDisplayAreas = getAxisLabelDisplayAreas(
/* size= */ mViewModel.size(),
- /* baselineX= */ mDividerWidth * .5f,
+ /* baselineX= */ mIndent.left + mDividerWidth * .5f,
/* offsetX= */ mDividerWidth + unitWidth,
baselineY,
/* shiftFirstAndLast= */ true);
@@ -402,7 +411,7 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick
drawAxisLabels(canvas, axisLabelDisplayAreas, baselineY);
}
// Draws each vertical dividers.
- float startX = mDividerWidth * .5f;
+ float startX = mDividerWidth * .5f + mIndent.left;
for (int index = 0; index < dividerCount; index++) {
float dividerY = bottomY;
if (mViewModel.axisLabelPosition() == BETWEEN_TRAPEZOIDS
@@ -416,8 +425,9 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick
final float nextX = startX + mDividerWidth + unitWidth;
// Updates the trapezoid slots for drawing.
if (index < mTrapezoidSlots.length) {
- mTrapezoidSlots[index].mLeft = round(startX + trapezoidSlotOffset);
- mTrapezoidSlots[index].mRight = round(nextX - trapezoidSlotOffset);
+ final int trapezoidIndex = isRTL() ? mTrapezoidSlots.length - index - 1 : index;
+ mTrapezoidSlots[trapezoidIndex].mLeft = round(startX + trapezoidSlotOffset);
+ mTrapezoidSlots[trapezoidIndex].mRight = round(nextX - trapezoidSlotOffset);
}
startX = nextX;
}
@@ -509,10 +519,20 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick
return displayAreas[leftIndex].right + mTextPadding * 2.3f > displayAreas[rightIndex].left;
}
+ private boolean isRTL() {
+ return mLayoutDirection == View.LAYOUT_DIRECTION_RTL;
+ }
+
private void drawAxisLabelText(
- Canvas canvas, final int index, final Rect displayArea, final float baselineY) {
+ Canvas canvas, int index, final Rect displayArea, final float baselineY) {
mTextPaint.setColor(mTrapezoidSolidColor);
mTextPaint.setTextAlign(Paint.Align.CENTER);
+ // Reverse the sort of axis labels for RTL
+ if (isRTL()) {
+ index = mViewModel.axisLabelPosition() == BETWEEN_TRAPEZOIDS
+ ? mViewModel.size() - index - 1 // for hourly
+ : mViewModel.size() - index - 2; // for daily
+ }
canvas.drawText(
mViewModel.getText(index),
displayArea.centerX(),
@@ -548,10 +568,16 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick
mHoveredIndex);
mTrapezoidPaint.setColor(isHoverState ? mTrapezoidHoverColor : trapezoidColor);
- final float leftTop = round(
+ float leftTop = round(
trapezoidBottom - requireNonNull(mViewModel.getLevel(index)) * unitHeight);
- final float rightTop = round(trapezoidBottom
+ float rightTop = round(trapezoidBottom
- requireNonNull(mViewModel.getLevel(index + 1)) * unitHeight);
+ // Mirror the shape of the trapezoid for RTL
+ if (isRTL()) {
+ float temp = leftTop;
+ leftTop = rightTop;
+ rightTop = temp;
+ }
trapezoidPath.reset();
trapezoidPath.moveTo(mTrapezoidSlots[index].mLeft, trapezoidBottom);
trapezoidPath.lineTo(mTrapezoidSlots[index].mLeft, leftTop);
diff --git a/src/com/android/settings/wifi/WifiEntryPreference.java b/src/com/android/settings/wifi/WifiEntryPreference.java
index 5b448870016..7206666b576 100644
--- a/src/com/android/settings/wifi/WifiEntryPreference.java
+++ b/src/com/android/settings/wifi/WifiEntryPreference.java
@@ -15,6 +15,8 @@
*/
package com.android.settings.wifi;
+import static com.android.settingslib.wifi.WifiUtils.getHotspotIconResource;
+
import android.annotation.Nullable;
import android.content.Context;
import android.content.res.Resources;
@@ -37,6 +39,7 @@ import com.android.settingslib.RestrictedPreference;
import com.android.settingslib.Utils;
import com.android.settingslib.wifi.WifiUtils;
import com.android.wifitrackerlib.BaseWifiTracker;
+import com.android.wifitrackerlib.HotspotNetworkEntry;
import com.android.wifitrackerlib.WifiEntry;
/**
@@ -145,13 +148,17 @@ public class WifiEntryPreference extends RestrictedPreference implements
*/
public void refresh() {
setTitle(mWifiEntry.getTitle());
- final int level = mWifiEntry.getLevel();
- final boolean showX = mWifiEntry.shouldShowXLevelIcon();
- if (level != mLevel || showX != mShowX) {
- mLevel = level;
- mShowX = showX;
- updateIcon(mShowX, mLevel);
- notifyChanged();
+ if (mWifiEntry instanceof HotspotNetworkEntry) {
+ updateHotspotIcon(((HotspotNetworkEntry) mWifiEntry).getDeviceType());
+ } else {
+ int level = mWifiEntry.getLevel();
+ boolean showX = mWifiEntry.shouldShowXLevelIcon();
+
+ if (level != mLevel || showX != mShowX) {
+ mLevel = level;
+ mShowX = showX;
+ updateIcon(mShowX, mLevel);
+ }
}
setSummary(mWifiEntry.getSummary(false /* concise */));
@@ -201,14 +208,7 @@ public class WifiEntryPreference extends RestrictedPreference implements
return accent ? android.R.attr.colorAccent : android.R.attr.colorControlNormal;
}
- @VisibleForTesting
- void updateIcon(boolean showX, int level) {
- if (level == -1) {
- setIcon(null);
- return;
- }
-
- final Drawable drawable = mIconInjector.getIcon(showX, level);
+ private void setIconWithTint(Drawable drawable) {
if (drawable != null) {
// Must use Drawable#setTintList() instead of Drawable#setTint() to show the grey
// icon when the preference is disabled.
@@ -219,6 +219,20 @@ public class WifiEntryPreference extends RestrictedPreference implements
}
}
+ @VisibleForTesting
+ void updateIcon(boolean showX, int level) {
+ if (level == -1) {
+ setIcon(null);
+ return;
+ }
+ setIconWithTint(mIconInjector.getIcon(showX, level));
+ }
+
+ @VisibleForTesting
+ void updateHotspotIcon(int deviceType) {
+ setIconWithTint(getContext().getDrawable(getHotspotIconResource(deviceType)));
+ }
+
@Nullable
private StateListDrawable getFrictionStateListDrawable() {
TypedArray frictionSld;
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/stylus/StylusDevicesControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/stylus/StylusDevicesControllerTest.java
index 1fcf396f31c..3c459de3792 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/stylus/StylusDevicesControllerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/stylus/StylusDevicesControllerTest.java
@@ -272,6 +272,20 @@ public class StylusDevicesControllerTest {
NOTES_APP_LABEL.toString()));
}
+ @Test
+ public void defaultNotesPreference_noApplicationInfo_showsBlankSummary()
+ throws PackageManager.NameNotFoundException {
+ when(mPm.getApplicationInfo(eq(NOTES_PACKAGE_NAME),
+ any(PackageManager.ApplicationInfoFlags.class))).thenReturn(null);
+
+ showScreen(mController);
+
+ Preference defaultNotesPref = mPreferenceContainer.getPreference(0);
+ assertThat(defaultNotesPref.getTitle().toString()).isEqualTo(
+ mContext.getString(R.string.stylus_default_notes_app));
+ assertThat(defaultNotesPref.getSummary().toString()).isEqualTo("");
+ }
+
@Test
public void defaultNotesPreference_roleHolderChanges_updatesPreference() {
showScreen(mController);
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiEntryPreferenceTest.java b/tests/robotests/src/com/android/settings/wifi/WifiEntryPreferenceTest.java
index a60b5313730..316beb37f70 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiEntryPreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiEntryPreferenceTest.java
@@ -18,11 +18,15 @@ package com.android.settings.wifi;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.graphics.drawable.Drawable;
+import android.net.wifi.sharedconnectivity.app.NetworkProviderInfo;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
@@ -31,6 +35,7 @@ import androidx.preference.PreferenceViewHolder;
import com.android.settingslib.R;
import com.android.settingslib.wifi.WifiUtils;
+import com.android.wifitrackerlib.HotspotNetworkEntry;
import com.android.wifitrackerlib.WifiEntry;
import org.junit.Before;
@@ -52,6 +57,8 @@ public class WifiEntryPreferenceTest {
@Mock
private WifiEntry mMockWifiEntry;
@Mock
+ private HotspotNetworkEntry mHotspotNetworkEntry;
+ @Mock
private WifiUtils.InternetIconInjector mMockIconInjector;
@Mock
@@ -256,4 +263,26 @@ public class WifiEntryPreferenceTest {
public void getSecondTargetResId_shouldNotReturnZero() {
assertThat(mPref.getSecondTargetResId()).isNotEqualTo(0);
}
+
+ @Test
+ public void refresh_itsHotspotNetworkEntry_shouldUpdateHotspotIcon() {
+ int deviceType = NetworkProviderInfo.DEVICE_TYPE_PHONE;
+ when(mHotspotNetworkEntry.getDeviceType()).thenReturn(deviceType);
+ WifiEntryPreference pref = spy(
+ new WifiEntryPreference(mContext, mHotspotNetworkEntry, mMockIconInjector));
+
+ pref.refresh();
+
+ verify(pref).updateHotspotIcon(deviceType);
+ }
+
+ @Test
+ public void refresh_notHotspotNetworkEntry_shouldNotUpdateHotspotIcon() {
+ WifiEntryPreference pref = spy(
+ new WifiEntryPreference(mContext, mMockWifiEntry, mMockIconInjector));
+
+ pref.refresh();
+
+ verify(pref, never()).updateHotspotIcon(anyInt());
+ }
}