Merge changes from topics "apply_fast_pair_icon", "bt_color_icon"
* changes: According Bluetooth device type to get icon Add method to get rainbow bt icon Separate library from SettingsLib
This commit is contained in:
committed by
Android (Google) Code Review
commit
439c06ba28
13
packages/SettingsLib/AdaptiveIcon/Android.bp
Normal file
13
packages/SettingsLib/AdaptiveIcon/Android.bp
Normal file
@@ -0,0 +1,13 @@
|
||||
android_library {
|
||||
name: "SettingsLibAdaptiveIcon",
|
||||
|
||||
srcs: ["src/**/*.java"],
|
||||
resource_dirs: ["res"],
|
||||
|
||||
static_libs: [
|
||||
"androidx.annotation_annotation",
|
||||
"SettingsLibTile"
|
||||
],
|
||||
|
||||
min_sdk_version: "21",
|
||||
}
|
||||
23
packages/SettingsLib/AdaptiveIcon/AndroidManifest.xml
Normal file
23
packages/SettingsLib/AdaptiveIcon/AndroidManifest.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?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.
|
||||
-->
|
||||
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.android.settingslib.widget">
|
||||
|
||||
<uses-sdk android:minSdkVersion="21" />
|
||||
|
||||
</manifest>
|
||||
21
packages/SettingsLib/AdaptiveIcon/res/values/colors.xml
Normal file
21
packages/SettingsLib/AdaptiveIcon/res/values/colors.xml
Normal file
@@ -0,0 +1,21 @@
|
||||
<?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.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<color name="homepage_generic_icon_background">#1A73E8</color>
|
||||
|
||||
<color name="bt_outline_color">#1f000000</color> <!-- icon outline color -->
|
||||
</resources>
|
||||
24
packages/SettingsLib/AdaptiveIcon/res/values/dimens.xml
Normal file
24
packages/SettingsLib/AdaptiveIcon/res/values/dimens.xml
Normal file
@@ -0,0 +1,24 @@
|
||||
<?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.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<!-- Dashboard foreground image inset (from background edge to foreground edge) -->
|
||||
<dimen name="dashboard_tile_foreground_image_inset">6dp</dimen>
|
||||
|
||||
<!-- Stroke size of adaptive outline -->
|
||||
<dimen name="adaptive_outline_stroke">1dp</dimen>
|
||||
</resources>
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* 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.settingslib.widget;
|
||||
|
||||
import static androidx.annotation.VisibleForTesting.NONE;
|
||||
|
||||
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_BACKGROUND_ARGB;
|
||||
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_BACKGROUND_HINT;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.LayerDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.settingslib.drawer.Tile;
|
||||
|
||||
/**
|
||||
* Adaptive icon that can set background color
|
||||
*/
|
||||
public class AdaptiveIcon extends LayerDrawable {
|
||||
|
||||
private static final String TAG = "AdaptiveHomepageIcon";
|
||||
|
||||
@VisibleForTesting(otherwise = NONE)
|
||||
int mBackgroundColor = -1;
|
||||
private AdaptiveConstantState mAdaptiveConstantState;
|
||||
|
||||
public AdaptiveIcon(Context context, Drawable foreground) {
|
||||
super(new Drawable[]{
|
||||
new AdaptiveIconShapeDrawable(context.getResources()),
|
||||
foreground
|
||||
});
|
||||
final int insetPx = context.getResources()
|
||||
.getDimensionPixelSize(R.dimen.dashboard_tile_foreground_image_inset);
|
||||
setLayerInset(1 /* index */, insetPx, insetPx, insetPx, insetPx);
|
||||
mAdaptiveConstantState = new AdaptiveConstantState(context, foreground);
|
||||
}
|
||||
|
||||
/**
|
||||
* According {@code tile} metaData to set background color
|
||||
*/
|
||||
public void setBackgroundColor(Context context, Tile tile) {
|
||||
final Bundle metaData = tile.getMetaData();
|
||||
try {
|
||||
if (metaData != null) {
|
||||
// Load from bg.argb first
|
||||
int bgColor = metaData.getInt(META_DATA_PREFERENCE_ICON_BACKGROUND_ARGB,
|
||||
0 /* default */);
|
||||
// Not found, load from bg.hint
|
||||
if (bgColor == 0) {
|
||||
final int colorRes = metaData.getInt(META_DATA_PREFERENCE_ICON_BACKGROUND_HINT,
|
||||
0 /* default */);
|
||||
if (colorRes != 0) {
|
||||
bgColor = context.getPackageManager()
|
||||
.getResourcesForApplication(tile.getPackageName())
|
||||
.getColor(colorRes, null /* theme */);
|
||||
}
|
||||
}
|
||||
// If found anything, use it.
|
||||
if (bgColor != 0) {
|
||||
setBackgroundColor(bgColor);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
Log.e(TAG, "Failed to set background color for " + tile.getPackageName());
|
||||
}
|
||||
setBackgroundColor(context.getColor(R.color.homepage_generic_icon_background));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set background color by {@code color}
|
||||
*/
|
||||
public void setBackgroundColor(int color) {
|
||||
mBackgroundColor = color;
|
||||
getDrawable(0).setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
|
||||
Log.d(TAG, "Setting background color " + mBackgroundColor);
|
||||
mAdaptiveConstantState.mColor = color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstantState getConstantState() {
|
||||
return mAdaptiveConstantState;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static class AdaptiveConstantState extends ConstantState {
|
||||
Context mContext;
|
||||
Drawable mDrawable;
|
||||
int mColor;
|
||||
|
||||
AdaptiveConstantState(Context context, Drawable drawable) {
|
||||
this.mContext = context;
|
||||
this.mDrawable = drawable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Drawable newDrawable() {
|
||||
final AdaptiveIcon
|
||||
icon = new AdaptiveIcon(mContext, mDrawable);
|
||||
icon.setBackgroundColor(mColor);
|
||||
|
||||
return icon;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChangingConfigurations() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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.settingslib.widget;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.Resources.Theme;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.drawable.AdaptiveIconDrawable;
|
||||
import android.graphics.drawable.ShapeDrawable;
|
||||
import android.graphics.drawable.shapes.PathShape;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.PathParser;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Draws a filled {@link ShapeDrawable} using the path from {@link AdaptiveIconDrawable}.
|
||||
*/
|
||||
public class AdaptiveIconShapeDrawable extends ShapeDrawable {
|
||||
public AdaptiveIconShapeDrawable() {
|
||||
super();
|
||||
}
|
||||
|
||||
public AdaptiveIconShapeDrawable(Resources resources) {
|
||||
super();
|
||||
init(resources);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme)
|
||||
throws XmlPullParserException, IOException {
|
||||
super.inflate(r, parser, attrs, theme);
|
||||
init(r);
|
||||
}
|
||||
|
||||
private void init(Resources resources) {
|
||||
final float pathSize = AdaptiveIconDrawable.MASK_SIZE;
|
||||
final Path path = new Path(PathParser.createPathFromPathData(
|
||||
resources.getString(com.android.internal.R.string.config_icon_mask)));
|
||||
setShape(new PathShape(path, pathSize, pathSize));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* 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.settingslib.widget;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.AdaptiveIconDrawable;
|
||||
import android.graphics.drawable.DrawableWrapper;
|
||||
import android.util.PathParser;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
/**
|
||||
* Adaptive outline drawable with white plain background color and black outline
|
||||
*/
|
||||
public class AdaptiveOutlineDrawable extends DrawableWrapper {
|
||||
@VisibleForTesting
|
||||
final Paint mOutlinePaint;
|
||||
private Path mPath;
|
||||
private final int mInsetPx;
|
||||
private final Bitmap mBitmap;
|
||||
|
||||
public AdaptiveOutlineDrawable(Resources resources, Bitmap bitmap) {
|
||||
super(new AdaptiveIconShapeDrawable(resources));
|
||||
|
||||
getDrawable().setTint(Color.WHITE);
|
||||
mPath = new Path(PathParser.createPathFromPathData(
|
||||
resources.getString(com.android.internal.R.string.config_icon_mask)));
|
||||
mOutlinePaint = new Paint();
|
||||
mOutlinePaint.setColor(resources.getColor(R.color.bt_outline_color, null));
|
||||
mOutlinePaint.setStyle(Paint.Style.STROKE);
|
||||
mOutlinePaint.setStrokeWidth(resources.getDimension(R.dimen.adaptive_outline_stroke));
|
||||
mOutlinePaint.setAntiAlias(true);
|
||||
|
||||
mInsetPx = resources
|
||||
.getDimensionPixelSize(R.dimen.dashboard_tile_foreground_image_inset);
|
||||
mBitmap = bitmap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
super.draw(canvas);
|
||||
final Rect bounds = getBounds();
|
||||
final float pathSize = AdaptiveIconDrawable.MASK_SIZE;
|
||||
|
||||
final float scaleX = (bounds.right - bounds.left) / pathSize;
|
||||
final float scaleY = (bounds.bottom - bounds.top) / pathSize;
|
||||
|
||||
final int count = canvas.save();
|
||||
canvas.scale(scaleX, scaleY);
|
||||
// Draw outline
|
||||
canvas.drawPath(mPath, mOutlinePaint);
|
||||
canvas.restoreToCount(count);
|
||||
|
||||
// Draw the foreground icon
|
||||
canvas.drawBitmap(mBitmap, bounds.left + mInsetPx, bounds.top + mInsetPx, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntrinsicHeight() {
|
||||
return mBitmap.getHeight() + 2 * mInsetPx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntrinsicWidth() {
|
||||
return mBitmap.getWidth() + 2 * mInsetPx;
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@ android_library {
|
||||
"SettingsLibEntityHeaderWidgets",
|
||||
"SettingsLibBarChartPreference",
|
||||
"SettingsLibProgressBar",
|
||||
"SettingsLibAdaptiveIcon",
|
||||
],
|
||||
|
||||
// ANDROIDMK TRANSLATION ERROR: unsupported assignment to LOCAL_SHARED_JAVA_LIBRARIES
|
||||
|
||||
11
packages/SettingsLib/Tile/Android.bp
Normal file
11
packages/SettingsLib/Tile/Android.bp
Normal file
@@ -0,0 +1,11 @@
|
||||
android_library {
|
||||
name: "SettingsLibTile",
|
||||
|
||||
srcs: ["src/**/*.java"],
|
||||
|
||||
static_libs: [
|
||||
"androidx.annotation_annotation",
|
||||
],
|
||||
|
||||
min_sdk_version: "21",
|
||||
}
|
||||
23
packages/SettingsLib/Tile/AndroidManifest.xml
Normal file
23
packages/SettingsLib/Tile/AndroidManifest.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?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.
|
||||
-->
|
||||
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.android.settingslib.drawer">
|
||||
|
||||
<uses-sdk android:minSdkVersion="21" />
|
||||
|
||||
</manifest>
|
||||
@@ -1,11 +1,11 @@
|
||||
/**
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
/*
|
||||
* 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
|
||||
* 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,
|
||||
@@ -13,7 +13,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settingslib.drawer;
|
||||
|
||||
import static java.lang.String.CASE_INSENSITIVE_ORDER;
|
||||
@@ -26,6 +25,9 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The category for handle {@link Tile}
|
||||
*/
|
||||
public class DashboardCategory implements Parcelable {
|
||||
|
||||
/**
|
||||
@@ -67,18 +69,30 @@ public class DashboardCategory implements Parcelable {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add tile
|
||||
*/
|
||||
public synchronized void addTile(Tile tile) {
|
||||
mTiles.add(tile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove tile
|
||||
*/
|
||||
public synchronized void removeTile(int n) {
|
||||
mTiles.remove(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get size of tile
|
||||
*/
|
||||
public int getTilesCount() {
|
||||
return mTiles.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tile
|
||||
*/
|
||||
public Tile getTile(int n) {
|
||||
return mTiles.get(n);
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
/**
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
/*
|
||||
* 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
|
||||
* 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,
|
||||
@@ -84,8 +84,8 @@ public class Tile implements Parcelable {
|
||||
mActivityPackage = in.readString();
|
||||
mActivityName = in.readString();
|
||||
mIntent = new Intent().setClassName(mActivityPackage, mActivityName);
|
||||
final int N = in.readInt();
|
||||
for (int i = 0; i < N; i++) {
|
||||
final int number = in.readInt();
|
||||
for (int i = 0; i < number; i++) {
|
||||
userHandle.add(UserHandle.CREATOR.createFromParcel(in));
|
||||
}
|
||||
mCategory = in.readString();
|
||||
@@ -101,9 +101,9 @@ public class Tile implements Parcelable {
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(mActivityPackage);
|
||||
dest.writeString(mActivityName);
|
||||
final int N = userHandle.size();
|
||||
dest.writeInt(N);
|
||||
for (int i = 0; i < N; i++) {
|
||||
final int size = userHandle.size();
|
||||
dest.writeInt(size);
|
||||
for (int i = 0; i < size; i++) {
|
||||
userHandle.get(i).writeToParcel(dest, flags);
|
||||
}
|
||||
dest.writeString(mCategory);
|
||||
@@ -151,6 +151,9 @@ public class Tile implements Parcelable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether title has order.
|
||||
*/
|
||||
public boolean hasOrder() {
|
||||
return mMetaData.containsKey(META_DATA_KEY_ORDER)
|
||||
&& mMetaData.get(META_DATA_KEY_ORDER) instanceof Integer;
|
||||
@@ -262,6 +265,9 @@ public class Tile implements Parcelable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether title has key.
|
||||
*/
|
||||
public boolean hasKey() {
|
||||
return mMetaData != null && mMetaData.containsKey(META_DATA_PREFERENCE_KEYHINT);
|
||||
}
|
||||
@@ -361,9 +367,12 @@ public class Tile implements Parcelable {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Check whether title is only have primary profile
|
||||
*/
|
||||
public boolean isPrimaryProfileOnly() {
|
||||
String profile = mMetaData != null ?
|
||||
mMetaData.getString(META_DATA_KEY_PROFILE) : PROFILE_ALL;
|
||||
String profile = mMetaData != null
|
||||
? mMetaData.getString(META_DATA_KEY_PROFILE) : PROFILE_ALL;
|
||||
profile = (profile != null ? profile : PROFILE_ALL);
|
||||
return TextUtils.equals(profile, PROFILE_PRIMARY);
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
* 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.
|
||||
@@ -11,7 +11,7 @@
|
||||
* 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
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.settingslib.drawer;
|
||||
|
||||
@@ -39,6 +39,10 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Utils is a helper class that contains profile key, meta data, settings action
|
||||
* and static methods for get icon or text from uri.
|
||||
*/
|
||||
public class TileUtils {
|
||||
|
||||
private static final boolean DEBUG_TIMING = false;
|
||||
33
packages/SettingsLib/res/drawable/ic_media_device.xml
Normal file
33
packages/SettingsLib/res/drawable/ic_media_device.xml
Normal file
@@ -0,0 +1,33 @@
|
||||
<?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.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="?android:attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:fillAlpha=".1"
|
||||
android:pathData="M0 0h24v24H0z" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0 0h24v24H0z" />
|
||||
<path
|
||||
android:fillColor="#000000"
|
||||
android:pathData="M21 3H3c-1.1 0-2 0.9-2 2v3h2V5h18v14h-7v2h7c1.1 0 2 -0.9 2-2V5c0-1.1 -0.9-2-2-2zM1 18v3h3c0-1.66-1.34-3-3-3zm0-4v2c2.76 0 5 2.24 5 5h2c0-3.87-3.13-7-7-7zm0-4v2c4.97 0 9 4.03 9 9h2c0-6.08-4.93-11-11-11z" />
|
||||
</vector>
|
||||
@@ -603,4 +603,26 @@
|
||||
<item>3</item><item>3</item>
|
||||
</array>
|
||||
|
||||
<!-- Bluetooth icon foreground colors -->
|
||||
<integer-array name="bt_icon_fg_colors">
|
||||
<item>@color/bt_color_icon_1</item>
|
||||
<item>@color/bt_color_icon_2</item>
|
||||
<item>@color/bt_color_icon_3</item>
|
||||
<item>@color/bt_color_icon_4</item>
|
||||
<item>@color/bt_color_icon_5</item>
|
||||
<item>@color/bt_color_icon_6</item>
|
||||
<item>@color/bt_color_icon_7</item>
|
||||
</integer-array>
|
||||
|
||||
<!-- Bluetooth icon background colors -->
|
||||
<integer-array name="bt_icon_bg_colors">
|
||||
<item>@color/bt_color_bg_1</item>
|
||||
<item>@color/bt_color_bg_2</item>
|
||||
<item>@color/bt_color_bg_3</item>
|
||||
<item>@color/bt_color_bg_4</item>
|
||||
<item>@color/bt_color_bg_5</item>
|
||||
<item>@color/bt_color_bg_6</item>
|
||||
<item>@color/bt_color_bg_7</item>
|
||||
</integer-array>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -19,4 +19,20 @@
|
||||
|
||||
<color name="usage_graph_dots">@*android:color/tertiary_device_default_settings</color>
|
||||
<color name="list_divider_color">#64000000</color>
|
||||
|
||||
<color name="bt_color_icon_1">#48a50e0e</color> <!-- 72% Material Red 900 -->
|
||||
<color name="bt_color_icon_2">#480d652d</color> <!-- 72% Material Green 900 -->
|
||||
<color name="bt_color_icon_3">#48e37400</color> <!-- 72% Material Yellow 900 -->
|
||||
<color name="bt_color_icon_4">#48b06000</color> <!-- 72% Material Orange 900 -->
|
||||
<color name="bt_color_icon_5">#489c166b</color> <!-- 72% Material Pink 900 -->
|
||||
<color name="bt_color_icon_6">#48681da8</color> <!-- 72% Material Purple 900 -->
|
||||
<color name="bt_color_icon_7">#48007b83</color> <!-- 72% Material Cyan 900 -->
|
||||
|
||||
<color name="bt_color_bg_1">#fad2cf</color> <!-- Material Red 100 -->
|
||||
<color name="bt_color_bg_2">#ceead6</color> <!-- Material Green 100 -->
|
||||
<color name="bt_color_bg_3">#feefc3</color> <!-- Material Yellow 100 -->
|
||||
<color name="bt_color_bg_4">#fedfc8</color> <!-- Material Orange 100 -->
|
||||
<color name="bt_color_bg_5">#fdcfe8</color> <!-- Material Pink 100 -->
|
||||
<color name="bt_color_bg_6">#e9d2fd</color> <!-- Material Purple 100 -->
|
||||
<color name="bt_color_bg_7">#cbf0f8</color> <!-- Material Cyan 100 -->
|
||||
</resources>
|
||||
|
||||
@@ -91,6 +91,7 @@
|
||||
<!-- How far to inset the rounded edges -->
|
||||
<dimen name="stat_sys_mobile_signal_circle_inset">0.9dp</dimen>
|
||||
|
||||
|
||||
<!-- Size of nearby icon -->
|
||||
<dimen name="bt_nearby_icon_size">24dp</dimen>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -1,18 +1,30 @@
|
||||
package com.android.settingslib.bluetooth;
|
||||
|
||||
import android.bluetooth.BluetoothClass;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothProfile;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.provider.MediaStore;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
|
||||
import androidx.annotation.DrawableRes;
|
||||
|
||||
import com.android.settingslib.R;
|
||||
import com.android.settingslib.widget.AdaptiveIcon;
|
||||
import com.android.settingslib.widget.AdaptiveOutlineDrawable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
public class BluetoothUtils {
|
||||
private static final String TAG = "BluetoothUtils";
|
||||
|
||||
public static final boolean V = false; // verbose logging
|
||||
public static final boolean D = true; // regular logging
|
||||
|
||||
@@ -112,4 +124,68 @@ public class BluetoothUtils {
|
||||
public static Drawable getBluetoothDrawable(Context context, @DrawableRes int resId) {
|
||||
return context.getDrawable(resId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get colorful bluetooth icon with description
|
||||
*/
|
||||
public static Pair<Drawable, String> getBtRainbowDrawableWithDescription(Context context,
|
||||
CachedBluetoothDevice cachedDevice) {
|
||||
final Pair<Drawable, String> pair = BluetoothUtils.getBtClassDrawableWithDescription(
|
||||
context, cachedDevice);
|
||||
final BluetoothDevice bluetoothDevice = cachedDevice.getDevice();
|
||||
final boolean untetheredHeadset = bluetoothDevice != null
|
||||
? Boolean.parseBoolean(bluetoothDevice.getMetadata(
|
||||
BluetoothDevice.METADATA_IS_UNTHETHERED_HEADSET))
|
||||
: false;
|
||||
final int iconSize = context.getResources().getDimensionPixelSize(
|
||||
R.dimen.bt_nearby_icon_size);
|
||||
final Resources resources = context.getResources();
|
||||
|
||||
// Deal with untethered headset
|
||||
if (untetheredHeadset) {
|
||||
final String uriString = bluetoothDevice != null
|
||||
? bluetoothDevice.getMetadata(BluetoothDevice.METADATA_MAIN_ICON)
|
||||
: null;
|
||||
final Uri iconUri = uriString != null ? Uri.parse(uriString) : null;
|
||||
if (iconUri != null) {
|
||||
try {
|
||||
final Bitmap bitmap = MediaStore.Images.Media.getBitmap(
|
||||
context.getContentResolver(), iconUri);
|
||||
if (bitmap != null) {
|
||||
final Bitmap resizedBitmap = Bitmap.createScaledBitmap(bitmap, iconSize,
|
||||
iconSize, false);
|
||||
bitmap.recycle();
|
||||
final AdaptiveOutlineDrawable drawable = new AdaptiveOutlineDrawable(
|
||||
resources, resizedBitmap);
|
||||
return new Pair<>(drawable, pair.second);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Failed to get drawable for: " + iconUri, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new Pair<>(buildBtRainbowDrawable(context,
|
||||
pair.first, cachedDevice.getAddress().hashCode()), pair.second);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build Bluetooth device icon with rainbow
|
||||
*/
|
||||
public static Drawable buildBtRainbowDrawable(Context context, Drawable drawable,
|
||||
int hashCode) {
|
||||
final Resources resources = context.getResources();
|
||||
|
||||
// Deal with normal headset
|
||||
final int[] iconFgColors = resources.getIntArray(R.array.bt_icon_fg_colors);
|
||||
final int[] iconBgColors = resources.getIntArray(R.array.bt_icon_bg_colors);
|
||||
|
||||
// get color index based on mac address
|
||||
final int index = Math.abs(hashCode % iconBgColors.length);
|
||||
drawable.setColorFilter(iconFgColors[index], PorterDuff.Mode.SRC_ATOP);
|
||||
final Drawable adaptiveIcon = new AdaptiveIcon(context, drawable);
|
||||
((AdaptiveIcon) adaptiveIcon).setBackgroundColor(iconBgColors[index]);
|
||||
|
||||
return adaptiveIcon;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,8 +18,11 @@ package com.android.settingslib.media;
|
||||
import android.bluetooth.BluetoothClass;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
|
||||
import com.android.settingslib.bluetooth.BluetoothUtils;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||
|
||||
/**
|
||||
@@ -48,9 +51,10 @@ public class BluetoothMediaDevice extends MediaDevice {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIcon() {
|
||||
//TODO(b/117129183): This is not final icon for bluetooth device, just for demo.
|
||||
return com.android.internal.R.drawable.ic_bt_headphones_a2dp;
|
||||
public Drawable getIcon() {
|
||||
final Pair<Drawable, String> pair = BluetoothUtils
|
||||
.getBtRainbowDrawableWithDescription(mContext, mCachedDevice);
|
||||
return pair.first;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -16,10 +16,14 @@
|
||||
package com.android.settingslib.media;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.mediarouter.media.MediaRouter;
|
||||
|
||||
import com.android.settingslib.R;
|
||||
import com.android.settingslib.bluetooth.BluetoothUtils;
|
||||
|
||||
/**
|
||||
* InfoMediaDevice extends MediaDevice to represents wifi device.
|
||||
*/
|
||||
@@ -46,9 +50,10 @@ public class InfoMediaDevice extends MediaDevice {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIcon() {
|
||||
//TODO(b/121083246): This is not final icon for cast device, just for demo.
|
||||
return com.android.internal.R.drawable.ic_settings_print;
|
||||
public Drawable getIcon() {
|
||||
//TODO(b/120669861): Return remote device icon uri once api is ready.
|
||||
return BluetoothUtils.buildBtRainbowDrawable(mContext,
|
||||
mContext.getDrawable(R.drawable.ic_media_device), getId().hashCode());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.android.settingslib.media;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.IntDef;
|
||||
@@ -70,11 +71,11 @@ public abstract class MediaDevice implements Comparable<MediaDevice> {
|
||||
public abstract String getSummary();
|
||||
|
||||
/**
|
||||
* Get resource id of MediaDevice.
|
||||
* Get icon of MediaDevice.
|
||||
*
|
||||
* @return resource id of MediaDevice.
|
||||
* @return drawable of icon.
|
||||
*/
|
||||
public abstract int getIcon();
|
||||
public abstract Drawable getIcon();
|
||||
|
||||
/**
|
||||
* Get unique ID that represent MediaDevice
|
||||
|
||||
@@ -16,10 +16,12 @@
|
||||
package com.android.settingslib.media;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.settingslib.R;
|
||||
import com.android.settingslib.bluetooth.A2dpProfile;
|
||||
import com.android.settingslib.bluetooth.BluetoothUtils;
|
||||
import com.android.settingslib.bluetooth.HearingAidProfile;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
|
||||
@@ -56,8 +58,9 @@ public class PhoneMediaDevice extends MediaDevice {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIcon() {
|
||||
return R.drawable.ic_smartphone;
|
||||
public Drawable getIcon() {
|
||||
return BluetoothUtils.buildBtRainbowDrawable(mContext,
|
||||
mContext.getDrawable(R.drawable.ic_smartphone), getId().hashCode());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -15,15 +15,20 @@
|
||||
*/
|
||||
package com.android.settingslib.bluetooth;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.bluetooth.BluetoothClass;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.Pair;
|
||||
|
||||
import com.android.settingslib.widget.AdaptiveIcon;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -38,6 +43,9 @@ public class BluetoothUtilsTest {
|
||||
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private CachedBluetoothDevice mCachedBluetoothDevice;
|
||||
@Mock
|
||||
private BluetoothDevice mBluetoothDevice;
|
||||
|
||||
private Context mContext;
|
||||
|
||||
@Before
|
||||
@@ -66,4 +74,16 @@ public class BluetoothUtilsTest {
|
||||
|
||||
verify(mContext).getDrawable(com.android.internal.R.drawable.ic_bt_laptop);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getBtRainbowDrawableWithDescription_normalHeadset_returnAdaptiveIcon() {
|
||||
when(mBluetoothDevice.getMetadata(
|
||||
BluetoothDevice.METADATA_IS_UNTHETHERED_HEADSET)).thenReturn("false");
|
||||
when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
|
||||
when(mCachedBluetoothDevice.getAddress()).thenReturn("1f:aa:bb");
|
||||
|
||||
assertThat(BluetoothUtils.getBtRainbowDrawableWithDescription(
|
||||
RuntimeEnvironment.application,
|
||||
mCachedBluetoothDevice).first).isInstanceOf(AdaptiveIcon.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* 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.settingslib.widget;
|
||||
|
||||
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_BACKGROUND_ARGB;
|
||||
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_BACKGROUND_HINT;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.graphics.drawable.ShapeDrawable;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.android.settingslib.R;
|
||||
import com.android.settingslib.drawer.CategoryKey;
|
||||
import com.android.settingslib.drawer.Tile;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class AdaptiveIconTest {
|
||||
|
||||
private Context mContext;
|
||||
private ActivityInfo mActivityInfo;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mActivityInfo = new ActivityInfo();
|
||||
mActivityInfo.packageName = mContext.getPackageName();
|
||||
mActivityInfo.name = "class";
|
||||
mActivityInfo.metaData = new Bundle();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createIcon_shouldSetBackgroundAndInset() {
|
||||
final AdaptiveIcon icon =
|
||||
new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK));
|
||||
|
||||
assertThat(icon.getNumberOfLayers()).isEqualTo(2);
|
||||
assertThat(icon.getDrawable(0)).isInstanceOf(AdaptiveIconShapeDrawable.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setBackgroundColor_shouldUpdateColorFilter() {
|
||||
final AdaptiveIcon icon =
|
||||
spy(new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK)));
|
||||
final ShapeDrawable background = mock(ShapeDrawable.class);
|
||||
when(icon.getDrawable(0)).thenReturn(background);
|
||||
|
||||
icon.setBackgroundColor(Color.BLUE);
|
||||
|
||||
verify(background).setColorFilter(Color.BLUE, PorterDuff.Mode.SRC_ATOP);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setBackgroundColor_externalTileWithBackgroundColorRawValue_shouldUpdateIcon() {
|
||||
final Tile tile = spy(new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE));
|
||||
mActivityInfo.metaData.putInt(META_DATA_PREFERENCE_ICON_BACKGROUND_ARGB, 0xff0000);
|
||||
doReturn(Icon.createWithResource(mContext, R.drawable.ic_system_update))
|
||||
.when(tile).getIcon(mContext);
|
||||
final AdaptiveIcon icon =
|
||||
new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK));
|
||||
|
||||
icon.setBackgroundColor(mContext, tile);
|
||||
assertThat(icon.mBackgroundColor).isEqualTo(0xff0000);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setBackgroundColor_tileWithoutBackgroundColor_shouldSetDefaultBackgroundColor() {
|
||||
final Tile tile = spy(new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE));
|
||||
doReturn(Icon.createWithResource(mContext, R.drawable.ic_system_update))
|
||||
.when(tile).getIcon(mContext);
|
||||
final AdaptiveIcon icon = new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK));
|
||||
|
||||
icon.setBackgroundColor(mContext, tile);
|
||||
|
||||
assertThat(icon.mBackgroundColor)
|
||||
.isEqualTo(mContext.getColor(R.color.homepage_generic_icon_background));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBindTile_externalTileWithBackgroundColorHint_shouldUpdateIcon() {
|
||||
final Tile tile = spy(new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE));
|
||||
mActivityInfo.metaData.putInt(META_DATA_PREFERENCE_ICON_BACKGROUND_HINT,
|
||||
R.color.bt_outline_color);
|
||||
doReturn(Icon.createWithResource(mContext, R.drawable.ic_system_update))
|
||||
.when(tile).getIcon(mContext);
|
||||
|
||||
final AdaptiveIcon icon =
|
||||
new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK));
|
||||
icon.setBackgroundColor(mContext, tile);
|
||||
|
||||
assertThat(icon.mBackgroundColor)
|
||||
.isEqualTo(mContext.getColor(R.color.bt_outline_color));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getConstantState_returnCorrectState() {
|
||||
final AdaptiveIcon icon =
|
||||
new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK));
|
||||
icon.setBackgroundColor(Color.YELLOW);
|
||||
|
||||
final AdaptiveIcon.AdaptiveConstantState state =
|
||||
(AdaptiveIcon.AdaptiveConstantState) icon.getConstantState();
|
||||
|
||||
assertThat(state.mColor).isEqualTo(Color.YELLOW);
|
||||
assertThat(state.mContext).isEqualTo(mContext);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.settingslib.widget;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Paint;
|
||||
|
||||
import com.android.settingslib.R;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class AdaptiveOutlineDrawableTest {
|
||||
|
||||
@Test
|
||||
public void constructor_initPaint() {
|
||||
final Resources resources = RuntimeEnvironment.application.getResources();
|
||||
final AdaptiveOutlineDrawable drawable = new AdaptiveOutlineDrawable(resources, null);
|
||||
|
||||
assertThat(drawable.mOutlinePaint.getStyle()).isEqualTo(Paint.Style.STROKE);
|
||||
assertThat(drawable.mOutlinePaint.getStrokeWidth()).isWithin(0.01f).of(
|
||||
resources.getDimension(R.dimen.adaptive_outline_stroke));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user