Rounded corners support, off by default.
Test: runtest systemui Bug: 33208650 Change-Id: I63e11e36268e277cc1c5e70651fa5248aa8b3fc0
This commit is contained in:
24
packages/SystemUI/res/drawable/rounded.xml
Normal file
24
packages/SystemUI/res/drawable/rounded.xml
Normal file
@@ -0,0 +1,24 @@
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="8dp"
|
||||
android:height="8dp"
|
||||
android:viewportWidth="8"
|
||||
android:viewportHeight="8">
|
||||
|
||||
<path
|
||||
android:fillColor="#000000"
|
||||
android:pathData="M8,0H0v8C0,3.6,3.6,0,8,0z" />
|
||||
|
||||
</vector>
|
||||
34
packages/SystemUI/res/layout/rounded_corners.xml
Normal file
34
packages/SystemUI/res/layout/rounded_corners.xml
Normal file
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
** Copyright 2012, 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.
|
||||
-->
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<ImageView
|
||||
android:id="@+id/left"
|
||||
android:layout_width="12dp"
|
||||
android:layout_height="12dp"
|
||||
android:tint="#ff000000"
|
||||
android:src="@drawable/rounded" />
|
||||
<ImageView
|
||||
android:id="@+id/right"
|
||||
android:layout_width="12dp"
|
||||
android:layout_height="12dp"
|
||||
android:tint="#ff000000"
|
||||
android:layout_gravity="end"
|
||||
android:src="@drawable/rounded" />
|
||||
</FrameLayout>
|
||||
@@ -792,4 +792,8 @@
|
||||
<dimen name="top_padding">0dp</dimen>
|
||||
<dimen name="bottom_padding">48dp</dimen>
|
||||
<dimen name="edge_margin">16dp</dimen>
|
||||
|
||||
<dimen name="rounded_corner_radius">0dp</dimen>
|
||||
<dimen name="rounded_corner_content_padding">0dp</dimen>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -77,6 +77,8 @@ import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
|
||||
import com.android.systemui.statusbar.policy.UserSwitcherController;
|
||||
import com.android.systemui.statusbar.policy.ZenModeController;
|
||||
import com.android.systemui.statusbar.policy.ZenModeControllerImpl;
|
||||
import com.android.systemui.tuner.TunablePadding;
|
||||
import com.android.systemui.tuner.TunablePadding.TunablePaddingService;
|
||||
import com.android.systemui.tuner.TunerService;
|
||||
import com.android.systemui.tuner.TunerServiceImpl;
|
||||
import com.android.systemui.util.leak.GarbageMonitor;
|
||||
@@ -268,6 +270,8 @@ public class Dependency extends SystemUI {
|
||||
|
||||
mProviders.put(ColorExtractor.class, () -> new ColorExtractor(mContext));
|
||||
|
||||
mProviders.put(TunablePaddingService.class, () -> new TunablePaddingService());
|
||||
|
||||
// Put all dependencies above here so the factory can override them if it wants.
|
||||
SystemUIFactory.getInstance().injectDependencies(mProviders, mContext);
|
||||
}
|
||||
|
||||
176
packages/SystemUI/src/com/android/systemui/RoundedCorners.java
Normal file
176
packages/SystemUI/src/com/android/systemui/RoundedCorners.java
Normal file
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.systemui;
|
||||
|
||||
import static com.android.systemui.tuner.TunablePadding.FLAG_START;
|
||||
import static com.android.systemui.tuner.TunablePadding.FLAG_END;
|
||||
|
||||
import android.app.Fragment;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewGroup.LayoutParams;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.android.systemui.R.id;
|
||||
import com.android.systemui.fragments.FragmentHostManager;
|
||||
import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
|
||||
import com.android.systemui.plugins.qs.QS;
|
||||
import com.android.systemui.statusbar.phone.CollapsedStatusBarFragment;
|
||||
import com.android.systemui.statusbar.phone.NavigationBarFragment;
|
||||
import com.android.systemui.statusbar.phone.StatusBar;
|
||||
import com.android.systemui.tuner.TunablePadding;
|
||||
import com.android.systemui.tuner.TunerService;
|
||||
import com.android.systemui.tuner.TunerService.Tunable;
|
||||
|
||||
public class RoundedCorners extends SystemUI implements Tunable {
|
||||
public static final String SIZE = "sysui_rounded_size";
|
||||
public static final String PADDING = "sysui_rounded_content_padding";
|
||||
|
||||
private int mRoundedDefault;
|
||||
private View mOverlay;
|
||||
private View mBottomOverlay;
|
||||
private float mDensity;
|
||||
private TunablePadding mQsPadding;
|
||||
private TunablePadding mStatusBarPadding;
|
||||
private TunablePadding mNavBarPadding;
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
mRoundedDefault = mContext.getResources().getDimensionPixelSize(
|
||||
R.dimen.rounded_corner_radius);
|
||||
if (mRoundedDefault == 0) {
|
||||
// No rounded corners on this device.
|
||||
return;
|
||||
}
|
||||
|
||||
mOverlay = LayoutInflater.from(mContext)
|
||||
.inflate(R.layout.rounded_corners, null);
|
||||
mOverlay.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
|
||||
mOverlay.findViewById(R.id.right).setRotation(90);
|
||||
|
||||
mContext.getSystemService(WindowManager.class)
|
||||
.addView(mOverlay, getWindowLayoutParams());
|
||||
mBottomOverlay = LayoutInflater.from(mContext)
|
||||
.inflate(R.layout.rounded_corners, null);
|
||||
mBottomOverlay.findViewById(R.id.right).setRotation(180);
|
||||
mBottomOverlay.findViewById(R.id.left).setRotation(270);
|
||||
WindowManager.LayoutParams layoutParams = getWindowLayoutParams();
|
||||
layoutParams.gravity = Gravity.BOTTOM;
|
||||
mContext.getSystemService(WindowManager.class)
|
||||
.addView(mBottomOverlay, layoutParams);
|
||||
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
mContext.getSystemService(WindowManager.class)
|
||||
.getDefaultDisplay().getMetrics(metrics);
|
||||
mDensity = metrics.density;
|
||||
|
||||
Dependency.get(TunerService.class).addTunable(this, SIZE);
|
||||
|
||||
// Add some padding to all the content near the edge of the screen.
|
||||
int padding = mContext.getResources().getDimensionPixelSize(
|
||||
R.dimen.rounded_corner_content_padding);
|
||||
StatusBar sb = getComponent(StatusBar.class);
|
||||
View statusBar = sb.getStatusBarWindow();
|
||||
|
||||
TunablePadding.addTunablePadding(statusBar.findViewById(R.id.keyguard_header), PADDING,
|
||||
padding, FLAG_END);
|
||||
|
||||
FragmentHostManager.get(sb.getNavigationBarWindow()).addTagListener(
|
||||
NavigationBarFragment.TAG,
|
||||
new TunablePaddingTagListener(padding, 0));
|
||||
|
||||
FragmentHostManager fragmentHostManager = FragmentHostManager.get(statusBar);
|
||||
fragmentHostManager.addTagListener(CollapsedStatusBarFragment.TAG,
|
||||
new TunablePaddingTagListener(padding, R.id.status_bar));
|
||||
fragmentHostManager.addTagListener(QS.TAG,
|
||||
new TunablePaddingTagListener(padding, R.id.header));
|
||||
}
|
||||
|
||||
private WindowManager.LayoutParams getWindowLayoutParams() {
|
||||
final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
LayoutParams.WRAP_CONTENT,
|
||||
WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
|
||||
0
|
||||
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
|
||||
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
|
||||
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
|
||||
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
|
||||
| WindowManager.LayoutParams.FLAG_SLIPPERY
|
||||
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
|
||||
| WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
|
||||
,
|
||||
PixelFormat.TRANSLUCENT);
|
||||
lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
|
||||
lp.setTitle("RoundedOverlay");
|
||||
lp.gravity = Gravity.TOP;
|
||||
return lp;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onTuningChanged(String key, String newValue) {
|
||||
if (mOverlay == null) return;
|
||||
if (SIZE.equals(key)) {
|
||||
int size = mRoundedDefault;
|
||||
try {
|
||||
size = (int) (Integer.parseInt(newValue) * mDensity);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
setSize(mOverlay.findViewById(R.id.left), size);
|
||||
setSize(mOverlay.findViewById(R.id.right), size);
|
||||
setSize(mBottomOverlay.findViewById(R.id.left), size);
|
||||
setSize(mBottomOverlay.findViewById(R.id.right), size);
|
||||
}
|
||||
}
|
||||
|
||||
private void setSize(View view, int pixelSize) {
|
||||
LayoutParams params = view.getLayoutParams();
|
||||
params.width = pixelSize;
|
||||
params.height = pixelSize;
|
||||
view.setLayoutParams(params);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static class TunablePaddingTagListener implements FragmentListener {
|
||||
|
||||
private final int mPadding;
|
||||
private final int mId;
|
||||
private TunablePadding mTunablePadding;
|
||||
|
||||
public TunablePaddingTagListener(int padding, int id) {
|
||||
mPadding = padding;
|
||||
mId = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFragmentViewCreated(String tag, Fragment fragment) {
|
||||
if (mTunablePadding != null) {
|
||||
mTunablePadding.destroy();
|
||||
}
|
||||
View view = fragment.getView();
|
||||
if (mId != 0) {
|
||||
view = view.findViewById(mId);
|
||||
}
|
||||
mTunablePadding = TunablePadding.addTunablePadding(view, PADDING, mPadding,
|
||||
FLAG_START | FLAG_END);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -87,6 +87,7 @@ public class SystemUIApplication extends Application implements SysUiServiceProv
|
||||
GarbageMonitor.Service.class,
|
||||
LatencyTester.class,
|
||||
GlobalActionsComponent.class,
|
||||
RoundedCorners.class,
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -94,7 +94,7 @@ import java.util.Locale;
|
||||
*/
|
||||
public class NavigationBarFragment extends Fragment implements Callbacks {
|
||||
|
||||
private static final String TAG = "NavigationBar";
|
||||
public static final String TAG = "NavigationBar";
|
||||
private static final boolean DEBUG = false;
|
||||
private static final String EXTRA_DISABLE_STATE = "disabled_state";
|
||||
|
||||
|
||||
@@ -4632,6 +4632,10 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
return (mNavigationBar != null ? (NavigationBarView) mNavigationBar.getView() : null);
|
||||
}
|
||||
|
||||
public View getNavigationBarWindow() {
|
||||
return mNavigationBarView;
|
||||
}
|
||||
|
||||
public KeyguardBottomAreaView getKeyguardBottomAreaView() {
|
||||
return mKeyguardBottomArea;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.systemui.tuner;
|
||||
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.tuner.TunerService.Tunable;
|
||||
|
||||
/**
|
||||
* Version of Space that can be resized by a tunable setting.
|
||||
*/
|
||||
public class TunablePadding implements Tunable {
|
||||
|
||||
public static final int FLAG_START = 1;
|
||||
public static final int FLAG_END = 2;
|
||||
public static final int FLAG_TOP = 4;
|
||||
public static final int FLAG_BOTTOM = 8;
|
||||
|
||||
private final int mFlags;
|
||||
private final View mView;
|
||||
private final int mDefaultSize;
|
||||
private final float mDensity;
|
||||
|
||||
private TunablePadding(String key, int def, int flags, View view) {
|
||||
mDefaultSize = def;
|
||||
mFlags = flags;
|
||||
mView = view;
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
view.getContext().getSystemService(WindowManager.class)
|
||||
.getDefaultDisplay().getMetrics(metrics);
|
||||
mDensity = metrics.density;
|
||||
Dependency.get(TunerService.class).addTunable(this, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTuningChanged(String key, String newValue) {
|
||||
int dimen = mDefaultSize;
|
||||
if (newValue != null) {
|
||||
dimen = (int) (Integer.parseInt(newValue) * mDensity);
|
||||
}
|
||||
int left = mView.isLayoutRtl() ? FLAG_END : FLAG_START;
|
||||
int right = mView.isLayoutRtl() ? FLAG_START : FLAG_END;
|
||||
mView.setPadding(getPadding(dimen, left), getPadding(dimen, FLAG_TOP),
|
||||
getPadding(dimen, right), getPadding(dimen, FLAG_BOTTOM));
|
||||
}
|
||||
|
||||
private int getPadding(int dimen, int flag) {
|
||||
return ((mFlags & flag) != 0) ? dimen : 0;
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
Dependency.get(TunerService.class).removeTunable(this);
|
||||
}
|
||||
|
||||
// Exists for easy injecting in tests.
|
||||
public static class TunablePaddingService {
|
||||
public TunablePadding add(View view, String key, int defaultSize, int flags) {
|
||||
if (view == null) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
return new TunablePadding(key, defaultSize, flags, view);
|
||||
}
|
||||
}
|
||||
|
||||
public static TunablePadding addTunablePadding(View view, String key, int defaultSize,
|
||||
int flags) {
|
||||
return Dependency.get(TunablePaddingService.class).add(view, key, defaultSize, flags);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.systemui;
|
||||
|
||||
import static com.android.systemui.tuner.TunablePadding.FLAG_END;
|
||||
import static com.android.systemui.tuner.TunablePadding.FLAG_START;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.Fragment;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.view.Display;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.android.systemui.R.dimen;
|
||||
import com.android.systemui.RoundedCorners.TunablePaddingTagListener;
|
||||
import com.android.systemui.fragments.FragmentHostManager;
|
||||
import com.android.systemui.fragments.FragmentService;
|
||||
import com.android.systemui.statusbar.phone.StatusBar;
|
||||
import com.android.systemui.statusbar.phone.StatusBarWindowView;
|
||||
import com.android.systemui.tuner.TunablePadding;
|
||||
import com.android.systemui.tuner.TunablePadding.TunablePaddingService;
|
||||
import com.android.systemui.tuner.TunerService;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
public class RoundedCornersTest extends SysuiTestCase {
|
||||
|
||||
private RoundedCorners mRoundedCorners;
|
||||
private StatusBar mStatusBar;
|
||||
private WindowManager mWindowManager;
|
||||
private FragmentService mFragmentService;
|
||||
private FragmentHostManager mFragmentHostManager;
|
||||
private TunerService mTunerService;
|
||||
private StatusBarWindowView mView;
|
||||
private TunablePaddingService mTunablePaddingService;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
mStatusBar = mock(StatusBar.class);
|
||||
mWindowManager = mock(WindowManager.class);
|
||||
mView = spy(new StatusBarWindowView(mContext, null));
|
||||
when(mStatusBar.getStatusBarWindow()).thenReturn(mView);
|
||||
mContext.putComponent(StatusBar.class, mStatusBar);
|
||||
|
||||
Display display = mContext.getSystemService(WindowManager.class).getDefaultDisplay();
|
||||
when(mWindowManager.getDefaultDisplay()).thenReturn(display);
|
||||
mContext.addMockSystemService(WindowManager.class, mWindowManager);
|
||||
|
||||
mFragmentService = mDependency.injectMockDependency(FragmentService.class);
|
||||
mFragmentHostManager = mock(FragmentHostManager.class);
|
||||
when(mFragmentService.getFragmentHostManager(any())).thenReturn(mFragmentHostManager);
|
||||
|
||||
mTunerService = mDependency.injectMockDependency(TunerService.class);
|
||||
|
||||
mRoundedCorners = new RoundedCorners();
|
||||
mRoundedCorners.mContext = mContext;
|
||||
mRoundedCorners.mComponents = mContext.getComponents();
|
||||
|
||||
mTunablePaddingService = mDependency.injectMockDependency(TunablePaddingService.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoRounding() {
|
||||
mContext.getOrCreateTestableResources().addOverride(dimen.rounded_corner_radius, 0);
|
||||
|
||||
mRoundedCorners.start();
|
||||
// No views added.
|
||||
verify(mWindowManager, never()).addView(any(), any());
|
||||
// No Fragments watched.
|
||||
verify(mFragmentHostManager, never()).addTagListener(any(), any());
|
||||
// No Tuners tuned.
|
||||
verify(mTunerService, never()).addTunable(any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRounding() {
|
||||
mContext.getOrCreateTestableResources().addOverride(dimen.rounded_corner_radius, 20);
|
||||
|
||||
mRoundedCorners.start();
|
||||
// Add 2 windows for rounded corners (top and bottom).
|
||||
verify(mWindowManager, times(2)).addView(any(), any());
|
||||
|
||||
// Add 3 tag listeners for each of the fragments that are needed.
|
||||
verify(mFragmentHostManager, times(3)).addTagListener(any(), any());
|
||||
// One tunable.
|
||||
verify(mTunerService, times(1)).addTunable(any(), any());
|
||||
// One TunablePadding.
|
||||
verify(mTunablePaddingService, times(1)).add(any(), anyString(), anyInt(), anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPaddingTagListener() {
|
||||
TunablePaddingTagListener tagListener = new TunablePaddingTagListener(14, 5);
|
||||
View v = mock(View.class);
|
||||
View child = mock(View.class);
|
||||
Fragment f = mock(Fragment.class);
|
||||
TunablePadding padding = mock(TunablePadding.class);
|
||||
|
||||
when(mTunablePaddingService.add(any(), anyString(), anyInt(), anyInt()))
|
||||
.thenReturn(padding);
|
||||
when(f.getView()).thenReturn(v);
|
||||
when(v.findViewById(5)).thenReturn(child);
|
||||
|
||||
// Trigger callback and verify we get a TunablePadding created.
|
||||
tagListener.onFragmentViewCreated(null, f);
|
||||
verify(mTunablePaddingService).add(eq(child), eq(RoundedCorners.PADDING), eq(14),
|
||||
eq(FLAG_START | FLAG_END));
|
||||
|
||||
// Call again and verify destroy is called.
|
||||
tagListener.onFragmentViewCreated(null, f);
|
||||
verify(padding).destroy();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -31,6 +31,11 @@ public class SysuiTestableContext extends TestableContext implements SysUiServic
|
||||
super(base, check);
|
||||
}
|
||||
|
||||
public ArrayMap<Class<?>, Object> getComponents() {
|
||||
if (mComponents == null) mComponents = new ArrayMap<>();
|
||||
return mComponents;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T getComponent(Class<T> interfaceType) {
|
||||
return (T) (mComponents != null ? mComponents.get(interfaceType) : null);
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.systemui.tuner;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockito.Mockito.withSettings;
|
||||
|
||||
import android.testing.LeakCheck.Tracker;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.android.systemui.utils.leaks.LeakCheckedTest;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TunablePaddingTest extends LeakCheckedTest {
|
||||
|
||||
private static final String KEY = "KEY";
|
||||
private static final int DEFAULT = 42;
|
||||
private View mView;
|
||||
private TunablePadding mTunablePadding;
|
||||
private TunerService mTunerService;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
|
||||
mView = mock(View.class, withSettings().spiedInstance(new View(mContext)));
|
||||
|
||||
mTunerService = mDependency.injectMockDependency(TunerService.class);
|
||||
Tracker tracker = mLeakCheck.getTracker("tuner");
|
||||
doAnswer(invocation -> {
|
||||
tracker.getLeakInfo(invocation.getArguments()[0]).addAllocation(new Throwable());
|
||||
return null;
|
||||
}).when(mTunerService).addTunable(any(), any());
|
||||
doAnswer(invocation -> {
|
||||
tracker.getLeakInfo(invocation.getArguments()[0]).clearAllocations();
|
||||
return null;
|
||||
}).when(mTunerService).removeTunable(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFlags() {
|
||||
mTunablePadding = TunablePadding.addTunablePadding(mView, KEY, DEFAULT,
|
||||
TunablePadding.FLAG_START);
|
||||
mTunablePadding.onTuningChanged(null, null);
|
||||
verify(mView).setPadding(eq(DEFAULT), eq(0), eq(0), eq(0));
|
||||
mTunablePadding.destroy();
|
||||
|
||||
mTunablePadding = TunablePadding.addTunablePadding(mView, KEY, DEFAULT,
|
||||
TunablePadding.FLAG_TOP);
|
||||
mTunablePadding.onTuningChanged(null, null);
|
||||
verify(mView).setPadding(eq(0), eq(DEFAULT), eq(0), eq(0));
|
||||
mTunablePadding.destroy();
|
||||
|
||||
mTunablePadding = TunablePadding.addTunablePadding(mView, KEY, DEFAULT,
|
||||
TunablePadding.FLAG_END);
|
||||
mTunablePadding.onTuningChanged(null, null);
|
||||
verify(mView).setPadding(eq(0), eq(0), eq(DEFAULT), eq(0));
|
||||
mTunablePadding.destroy();
|
||||
|
||||
mTunablePadding = TunablePadding.addTunablePadding(mView, KEY, DEFAULT,
|
||||
TunablePadding.FLAG_BOTTOM);
|
||||
mTunablePadding.onTuningChanged(null, null);
|
||||
verify(mView).setPadding(eq(0), eq(0), eq(0), eq(DEFAULT));
|
||||
mTunablePadding.destroy();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRtl() {
|
||||
when(mView.isLayoutRtl()).thenReturn(true);
|
||||
|
||||
mTunablePadding = TunablePadding.addTunablePadding(mView, KEY, DEFAULT,
|
||||
TunablePadding.FLAG_END);
|
||||
mTunablePadding.onTuningChanged(null, null);
|
||||
verify(mView).setPadding(eq(DEFAULT), eq(0), eq(0), eq(0));
|
||||
mTunablePadding.destroy();
|
||||
|
||||
mTunablePadding = TunablePadding.addTunablePadding(mView, KEY, DEFAULT,
|
||||
TunablePadding.FLAG_START);
|
||||
mTunablePadding.onTuningChanged(null, null);
|
||||
verify(mView).setPadding(eq(0), eq(0), eq(DEFAULT), eq(0));
|
||||
mTunablePadding.destroy();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTuning() {
|
||||
int value = 3;
|
||||
mTunablePadding = TunablePadding.addTunablePadding(mView, KEY, DEFAULT,
|
||||
TunablePadding.FLAG_START);
|
||||
mTunablePadding.onTuningChanged(KEY, String.valueOf(value));
|
||||
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
mContext.getSystemService(WindowManager.class).getDefaultDisplay().getMetrics(metrics);
|
||||
int output = (int) (metrics.density * value);
|
||||
verify(mView).setPadding(eq(output), eq(0), eq(0), eq(0));
|
||||
|
||||
mTunablePadding.destroy();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user