Added Complication implementations for Dream Weather, Clock Time, and Clock Time.

Implemented all three complications layer native widgets.

Bug: 213906528
Test: aTest DreamWeatherComplicationTest DreamClockTimeComplicationTest DreamClockDateComplicationTest

Change-Id: I24d8f58f0f8f4baa1ed64f6a9a7644825be5dd51
This commit is contained in:
Nick Ning
2022-01-27 15:11:50 +00:00
parent 1197b41951
commit 078fb82e83
17 changed files with 1091 additions and 28 deletions

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2022 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.
-->
<TextClock
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/date_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="@dimen/dream_overlay_complication_clock_date_padding_left"
android:paddingBottom="@dimen/dream_overlay_complication_clock_date_padding_bottom"
android:gravity="center_horizontal"
android:textColor="@android:color/white"
android:shadowColor="@color/keyguard_shadow_color"
android:shadowRadius="?attr/shadowRadius"
android:format12Hour="EEE, MMM d"
android:format24Hour="EEE, MMM d"
android:textSize="@dimen/dream_overlay_complication_clock_date_text_size"/>

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2022 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.
-->
<TextClock
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/time_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="@dimen/dream_overlay_complication_clock_time_padding_left"
android:fontFamily="sans-serif-thin"
android:textColor="@android:color/white"
android:format12Hour="h:mm"
android:format24Hour="kk:mm"
android:shadowColor="@color/keyguard_shadow_color"
android:shadowRadius="?attr/shadowRadius"
android:textSize="@dimen/dream_overlay_complication_clock_time_text_size"/>

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2022 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.
-->
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/weather_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="@dimen/dream_overlay_complication_weather_padding_left"
android:paddingBottom="@dimen/dream_overlay_complication_weather_padding_bottom"
android:textColor="@android:color/white"
android:shadowColor="@color/keyguard_shadow_color"
android:shadowRadius="?attr/shadowRadius"
android:textSize="@dimen/dream_overlay_complication_weather_text_size"/>

View File

@@ -20,34 +20,6 @@
android:id="@+id/dream_overlay_complications_layer"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextClock
android:id="@+id/time_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-thin"
android:format12Hour="h:mm"
android:format24Hour="kk:mm"
android:shadowColor="#B2000000"
android:shadowRadius="2.0"
android:singleLine="true"
android:textSize="72sp"
android:textColor="@android:color/white"
app:layout_constraintBottom_toTopOf="@+id/date_view"
app:layout_constraintStart_toStartOf="parent" />
<TextClock
android:id="@+id/date_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:shadowColor="#B2000000"
android:shadowRadius="2.0"
android:format12Hour="EEE, MMM d"
android:format24Hour="EEE, MMM d"
android:singleLine="true"
android:textSize="18sp"
android:textColor="@android:color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/time_view"
app:layout_constraintStart_toStartOf="@+id/time_view" />
<androidx.constraintlayout.widget.Guideline
android:layout_width="wrap_content"
android:layout_height="wrap_content"

View File

@@ -1345,6 +1345,16 @@
shade. -->
<dimen name="dream_overlay_notifications_drag_area_height">100dp</dimen>
<!-- Dream overlay complications related dimensions -->
<dimen name="dream_overlay_complication_clock_time_padding_left">50dp</dimen>
<dimen name="dream_overlay_complication_clock_time_text_size">72sp</dimen>
<dimen name="dream_overlay_complication_clock_date_padding_left">60dp</dimen>
<dimen name="dream_overlay_complication_clock_date_padding_bottom">50dp</dimen>
<dimen name="dream_overlay_complication_clock_date_text_size">18sp</dimen>
<dimen name="dream_overlay_complication_weather_padding_left">20dp</dimen>
<dimen name="dream_overlay_complication_weather_padding_bottom">50dp</dimen>
<dimen name="dream_overlay_complication_weather_text_size">18sp</dimen>
<!-- The position of the end guide, which dream overlay complications can align their start with
if their end is aligned with the parent end. Represented as the percentage over from the
start of the parent container. -->

View File

@@ -27,6 +27,9 @@ import com.android.systemui.biometrics.AuthController;
import com.android.systemui.clipboardoverlay.ClipboardListener;
import com.android.systemui.dreams.DreamOverlayRegistrant;
import com.android.systemui.dreams.SmartSpaceComplication;
import com.android.systemui.dreams.complication.DreamClockDateComplication;
import com.android.systemui.dreams.complication.DreamClockTimeComplication;
import com.android.systemui.dreams.complication.DreamWeatherComplication;
import com.android.systemui.globalactions.GlobalActionsComponent;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.keyguard.dagger.KeyguardModule;
@@ -234,4 +237,25 @@ public abstract class SystemUIBinder {
@ClassKey(MediaDreamSentinel.class)
public abstract CoreStartable bindMediaDreamSentinel(
MediaDreamSentinel sentinel);
/** Inject into DreamClockTimeComplication.Registrant */
@Binds
@IntoMap
@ClassKey(DreamClockTimeComplication.Registrant.class)
public abstract CoreStartable bindDreamClockTimeComplicationRegistrant(
DreamClockTimeComplication.Registrant registrant);
/** Inject into DreamClockDateComplication.Registrant */
@Binds
@IntoMap
@ClassKey(DreamClockDateComplication.Registrant.class)
public abstract CoreStartable bindDreamClockDateComplicationRegistrant(
DreamClockDateComplication.Registrant registrant);
/** Inject into DreamWeatherComplication.Registrant */
@Binds
@IntoMap
@ClassKey(DreamWeatherComplication.Registrant.class)
public abstract CoreStartable bindDreamWeatherComplicationRegistrant(
DreamWeatherComplication.Registrant registrant);
}

View File

@@ -0,0 +1,106 @@
/*
* Copyright (C) 2022 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.dreams.complication;
import static com.android.systemui.dreams.complication.dagger.DreamClockDateComplicationComponent.DreamClockDateComplicationModule.DREAM_CLOCK_DATE_COMPLICATION_LAYOUT_PARAMS;
import static com.android.systemui.dreams.complication.dagger.DreamClockDateComplicationComponent.DreamClockDateComplicationModule.DREAM_CLOCK_DATE_COMPLICATION_VIEW;
import android.content.Context;
import android.view.View;
import com.android.systemui.CoreStartable;
import com.android.systemui.dreams.DreamOverlayStateController;
import com.android.systemui.dreams.complication.dagger.DreamClockDateComplicationComponent;
import javax.inject.Inject;
import javax.inject.Named;
/**
* Clock Date Complication that produce Clock Date view holder.
*/
public class DreamClockDateComplication implements Complication {
DreamClockDateComplicationComponent.Factory mComponentFactory;
/**
* Default constructor for {@link DreamClockDateComplication}.
*/
@Inject
public DreamClockDateComplication(
DreamClockDateComplicationComponent.Factory componentFactory) {
mComponentFactory = componentFactory;
}
/**
* Create {@link DreamClockDateViewHolder}.
*/
@Override
public ViewHolder createView(ComplicationViewModel model) {
return mComponentFactory.create().getViewHolder();
}
/**
* {@link CoreStartable} responsbile for registering {@link DreamClockDateComplication} with
* SystemUI.
*/
public static class Registrant extends CoreStartable {
private final DreamOverlayStateController mDreamOverlayStateController;
private final DreamClockDateComplication mComplication;
/**
* Default constructor to register {@link DreamClockDateComplication}.
*/
@Inject
public Registrant(Context context,
DreamOverlayStateController dreamOverlayStateController,
DreamClockDateComplication dreamClockDateComplication) {
super(context);
mDreamOverlayStateController = dreamOverlayStateController;
mComplication = dreamClockDateComplication;
}
@Override
public void start() {
mDreamOverlayStateController.addComplication(mComplication);
}
}
/**
* ViewHolder to contain value/logic associated with a Clock Date Complication View.
*/
public static class DreamClockDateViewHolder implements ViewHolder {
private final View mView;
private final ComplicationLayoutParams mLayoutParams;
@Inject
DreamClockDateViewHolder(@Named(DREAM_CLOCK_DATE_COMPLICATION_VIEW) View view,
@Named(DREAM_CLOCK_DATE_COMPLICATION_LAYOUT_PARAMS)
ComplicationLayoutParams layoutParams) {
mView = view;
mLayoutParams = layoutParams;
}
@Override
public View getView() {
return mView;
}
@Override
public ComplicationLayoutParams getLayoutParams() {
return mLayoutParams;
}
}
}

View File

@@ -0,0 +1,106 @@
/*
* Copyright (C) 2022 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.dreams.complication;
import static com.android.systemui.dreams.complication.dagger.DreamClockTimeComplicationComponent.DreamClockTimeComplicationModule.DREAM_CLOCK_TIME_COMPLICATION_LAYOUT_PARAMS;
import static com.android.systemui.dreams.complication.dagger.DreamClockTimeComplicationComponent.DreamClockTimeComplicationModule.DREAM_CLOCK_TIME_COMPLICATION_VIEW;
import android.content.Context;
import android.view.View;
import com.android.systemui.CoreStartable;
import com.android.systemui.dreams.DreamOverlayStateController;
import com.android.systemui.dreams.complication.dagger.DreamClockTimeComplicationComponent;
import javax.inject.Inject;
import javax.inject.Named;
/**
* Clock Time Complication that produce Clock Time view holder.
*/
public class DreamClockTimeComplication implements Complication {
DreamClockTimeComplicationComponent.Factory mComponentFactory;
/**
* Default constructor for {@link DreamClockTimeComplication}.
*/
@Inject
public DreamClockTimeComplication(
DreamClockTimeComplicationComponent.Factory componentFactory) {
mComponentFactory = componentFactory;
}
/**
* Create {@link DreamClockTimeViewHolder}.
*/
@Override
public ViewHolder createView(ComplicationViewModel model) {
return mComponentFactory.create().getViewHolder();
}
/**
* {@link CoreStartable} responsbile for registering {@link DreamClockTimeComplication} with
* SystemUI.
*/
public static class Registrant extends CoreStartable {
private final DreamOverlayStateController mDreamOverlayStateController;
private final DreamClockTimeComplication mComplication;
/**
* Default constructor to register {@link DreamClockTimeComplication}.
*/
@Inject
public Registrant(Context context,
DreamOverlayStateController dreamOverlayStateController,
DreamClockTimeComplication dreamClockTimeComplication) {
super(context);
mDreamOverlayStateController = dreamOverlayStateController;
mComplication = dreamClockTimeComplication;
}
@Override
public void start() {
mDreamOverlayStateController.addComplication(mComplication);
}
}
/**
* ViewHolder to contain value/logic associated with a Clock Time Complication View.
*/
public static class DreamClockTimeViewHolder implements ViewHolder {
private final View mView;
private final ComplicationLayoutParams mLayoutParams;
@Inject
DreamClockTimeViewHolder(@Named(DREAM_CLOCK_TIME_COMPLICATION_VIEW) View view,
@Named(DREAM_CLOCK_TIME_COMPLICATION_LAYOUT_PARAMS)
ComplicationLayoutParams layoutParams) {
mView = view;
mLayoutParams = layoutParams;
}
@Override
public View getView() {
return mView;
}
@Override
public ComplicationLayoutParams getLayoutParams() {
return mLayoutParams;
}
}
}

View File

@@ -0,0 +1,180 @@
/*
* Copyright (C) 2022 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.dreams.complication;
import static com.android.systemui.dreams.complication.dagger.DreamWeatherComplicationComponent.DreamWeatherComplicationModule.DREAM_WEATHER_COMPLICATION_LAYOUT_PARAMS;
import static com.android.systemui.dreams.complication.dagger.DreamWeatherComplicationComponent.DreamWeatherComplicationModule.DREAM_WEATHER_COMPLICATION_VIEW;
import android.app.smartspace.SmartspaceAction;
import android.app.smartspace.SmartspaceTarget;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.text.TextUtils;
import android.widget.TextView;
import com.android.systemui.CoreStartable;
import com.android.systemui.R;
import com.android.systemui.dreams.DreamOverlayStateController;
import com.android.systemui.dreams.complication.dagger.DreamWeatherComplicationComponent;
import com.android.systemui.plugins.BcSmartspaceDataPlugin.SmartspaceTargetListener;
import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController;
import com.android.systemui.util.ViewController;
import javax.inject.Inject;
import javax.inject.Named;
/**
* Weather Complication that produce Weather view holder.
*/
public class DreamWeatherComplication implements Complication {
DreamWeatherComplicationComponent.Factory mComponentFactory;
/**
* Default constructor for {@link DreamWeatherComplication}.
*/
@Inject
public DreamWeatherComplication(
DreamWeatherComplicationComponent.Factory componentFactory) {
mComponentFactory = componentFactory;
}
/**
* Create {@link DreamWeatherViewHolder}.
*/
@Override
public ViewHolder createView(ComplicationViewModel model) {
return mComponentFactory.create().getViewHolder();
}
/**
* {@link CoreStartable} for registering {@link DreamWeatherComplication} with SystemUI.
*/
public static class Registrant extends CoreStartable {
private final LockscreenSmartspaceController mSmartSpaceController;
private final DreamOverlayStateController mDreamOverlayStateController;
private final DreamWeatherComplication mComplication;
/**
* Default constructor to register {@link DreamWeatherComplication}.
*/
@Inject
public Registrant(Context context,
LockscreenSmartspaceController smartspaceController,
DreamOverlayStateController dreamOverlayStateController,
DreamWeatherComplication dreamWeatherComplication) {
super(context);
mSmartSpaceController = smartspaceController;
mDreamOverlayStateController = dreamOverlayStateController;
mComplication = dreamWeatherComplication;
}
@Override
public void start() {
if (mSmartSpaceController.isEnabled()) {
mDreamOverlayStateController.addComplication(mComplication);
}
}
}
/**
* ViewHolder to contain value/logic associated with a Weather Complication View.
*/
public static class DreamWeatherViewHolder implements ViewHolder {
private final TextView mView;
private final ComplicationLayoutParams mLayoutParams;
private final DreamWeatherViewController mViewController;
@Inject
DreamWeatherViewHolder(
@Named(DREAM_WEATHER_COMPLICATION_VIEW) TextView view,
DreamWeatherViewController controller,
@Named(DREAM_WEATHER_COMPLICATION_LAYOUT_PARAMS)
ComplicationLayoutParams layoutParams) {
mView = view;
mLayoutParams = layoutParams;
mViewController = controller;
mViewController.init();
}
@Override
public TextView getView() {
return mView;
}
@Override
public ComplicationLayoutParams getLayoutParams() {
return mLayoutParams;
}
}
/**
* ViewController to contain value/logic associated with a Weather Complication View.
*/
static class DreamWeatherViewController extends ViewController<TextView> {
private final LockscreenSmartspaceController mSmartSpaceController;
private SmartspaceTargetListener mSmartspaceTargetListener;
@Inject
DreamWeatherViewController(
@Named(DREAM_WEATHER_COMPLICATION_VIEW) TextView view,
LockscreenSmartspaceController smartspaceController
) {
super(view);
mSmartSpaceController = smartspaceController;
}
@Override
protected void onViewAttached() {
mSmartspaceTargetListener = targets -> targets.forEach(
t -> {
if (t instanceof SmartspaceTarget
&& ((SmartspaceTarget) t).getFeatureType()
== SmartspaceTarget.FEATURE_WEATHER) {
final SmartspaceTarget target = (SmartspaceTarget) t;
final SmartspaceAction headerAction = target.getHeaderAction();
if (headerAction == null || TextUtils.isEmpty(
headerAction.getTitle())) {
return;
}
String temperature = headerAction.getTitle().toString();
mView.setText(temperature);
final Icon icon = headerAction.getIcon();
if (icon != null) {
final int iconSize =
getResources().getDimensionPixelSize(
R.dimen.smart_action_button_icon_size);
final Drawable iconDrawable = icon.loadDrawable(getContext());
iconDrawable.setBounds(0, 0, iconSize, iconSize);
mView.setCompoundDrawables(iconDrawable, null, null, null);
mView.setCompoundDrawablePadding(
getResources().getDimensionPixelSize(
R.dimen.smart_action_button_icon_padding));
}
}
});
mSmartSpaceController.addListener(mSmartspaceTargetListener);
}
@Override
protected void onViewDetached() {
mSmartSpaceController.removeListener(mSmartspaceTargetListener);
}
}
}

View File

@@ -0,0 +1,111 @@
/*
* Copyright (C) 2022 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.dreams.complication.dagger;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.android.internal.util.Preconditions;
import com.android.systemui.R;
import com.android.systemui.dreams.complication.ComplicationLayoutParams;
import com.android.systemui.dreams.complication.DreamClockDateComplication.DreamClockDateViewHolder;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import javax.inject.Named;
import javax.inject.Scope;
import dagger.Module;
import dagger.Provides;
import dagger.Subcomponent;
/**
* {@link DreamClockDateComplicationComponent} is responsible for generating dependencies
* surrounding the
* Clock Date {@link com.android.systemui.dreams.complication.Complication}, such as the layout
* details.
*/
@Subcomponent(modules = {
DreamClockDateComplicationComponent.DreamClockDateComplicationModule.class,
})
@DreamClockDateComplicationComponent.DreamClockDateComplicationScope
public interface DreamClockDateComplicationComponent {
/**
* Creates {@link DreamClockDateViewHolder}.
*/
DreamClockDateViewHolder getViewHolder();
@Documented
@Retention(RUNTIME)
@Scope
@interface DreamClockDateComplicationScope {
}
/**
* Generates {@link DreamClockDateComplicationComponent}.
*/
@Subcomponent.Factory
interface Factory {
DreamClockDateComplicationComponent create();
}
/**
* Scoped values for {@link DreamClockDateComplicationComponent}.
*/
@Module
interface DreamClockDateComplicationModule {
String DREAM_CLOCK_DATE_COMPLICATION_VIEW = "clock_date_complication_view";
String DREAM_CLOCK_DATE_COMPLICATION_LAYOUT_PARAMS =
"clock_date_complication_layout_params";
// Order weight of insert into parent container
int INSERT_ORDER_WEIGHT = 2;
/**
* Provides the complication view.
*/
@Provides
@DreamClockDateComplicationScope
@Named(DREAM_CLOCK_DATE_COMPLICATION_VIEW)
static View provideComplicationView(LayoutInflater layoutInflater) {
return Preconditions.checkNotNull(
layoutInflater.inflate(R.layout.dream_overlay_complication_clock_date,
null, false),
"R.layout.dream_overlay_complication_clock_date did not properly inflated");
}
/**
* Provides the layout parameters for the complication view.
*/
@Provides
@DreamClockDateComplicationScope
@Named(DREAM_CLOCK_DATE_COMPLICATION_LAYOUT_PARAMS)
static ComplicationLayoutParams provideLayoutParams() {
return new ComplicationLayoutParams(0,
ViewGroup.LayoutParams.WRAP_CONTENT,
ComplicationLayoutParams.POSITION_BOTTOM
| ComplicationLayoutParams.POSITION_START,
ComplicationLayoutParams.DIRECTION_END,
INSERT_ORDER_WEIGHT,
true);
}
}
}

View File

@@ -0,0 +1,111 @@
/*
* Copyright (C) 2022 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.dreams.complication.dagger;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.android.internal.util.Preconditions;
import com.android.systemui.R;
import com.android.systemui.dreams.complication.ComplicationLayoutParams;
import com.android.systemui.dreams.complication.DreamClockTimeComplication.DreamClockTimeViewHolder;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import javax.inject.Named;
import javax.inject.Scope;
import dagger.Module;
import dagger.Provides;
import dagger.Subcomponent;
/**
* {@link DreamClockTimeComplicationComponent} is responsible for generating dependencies
* surrounding the
* Clock Time {@link com.android.systemui.dreams.complication.Complication}, such as the layout
* details.
*/
@Subcomponent(modules = {
DreamClockTimeComplicationComponent.DreamClockTimeComplicationModule.class,
})
@DreamClockTimeComplicationComponent.DreamClockTimeComplicationScope
public interface DreamClockTimeComplicationComponent {
/**
* Creates {@link DreamClockTimeViewHolder}.
*/
DreamClockTimeViewHolder getViewHolder();
@Documented
@Retention(RUNTIME)
@Scope
@interface DreamClockTimeComplicationScope {
}
/**
* Generates {@link DreamClockTimeComplicationComponent}.
*/
@Subcomponent.Factory
interface Factory {
DreamClockTimeComplicationComponent create();
}
/**
* Scoped values for {@link DreamClockTimeComplicationComponent}.
*/
@Module
interface DreamClockTimeComplicationModule {
String DREAM_CLOCK_TIME_COMPLICATION_VIEW = "clock_time_complication_view";
String DREAM_CLOCK_TIME_COMPLICATION_LAYOUT_PARAMS =
"clock_time_complication_layout_params";
// Order weight of insert into parent container
int INSERT_ORDER_WEIGHT = 0;
/**
* Provides the complication view.
*/
@Provides
@DreamClockTimeComplicationScope
@Named(DREAM_CLOCK_TIME_COMPLICATION_VIEW)
static View provideComplicationView(LayoutInflater layoutInflater) {
return Preconditions.checkNotNull(
layoutInflater.inflate(R.layout.dream_overlay_complication_clock_time,
null, false),
"R.layout.dream_overlay_complication_clock_time did not properly inflated");
}
/**
* Provides the layout parameters for the complication view.
*/
@Provides
@DreamClockTimeComplicationScope
@Named(DREAM_CLOCK_TIME_COMPLICATION_LAYOUT_PARAMS)
static ComplicationLayoutParams provideLayoutParams() {
return new ComplicationLayoutParams(0,
ViewGroup.LayoutParams.WRAP_CONTENT,
ComplicationLayoutParams.POSITION_BOTTOM
| ComplicationLayoutParams.POSITION_START,
ComplicationLayoutParams.DIRECTION_UP,
INSERT_ORDER_WEIGHT,
true);
}
}
}

View File

@@ -0,0 +1,111 @@
/*
* Copyright (C) 2022 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.dreams.complication.dagger;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.TextView;
import com.android.internal.util.Preconditions;
import com.android.systemui.R;
import com.android.systemui.dreams.complication.ComplicationLayoutParams;
import com.android.systemui.dreams.complication.DreamWeatherComplication.DreamWeatherViewHolder;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import javax.inject.Named;
import javax.inject.Scope;
import dagger.Module;
import dagger.Provides;
import dagger.Subcomponent;
/**
* {@link DreamWeatherComplicationComponent} is responsible for generating dependencies surrounding
* the
* Clock Date {@link com.android.systemui.dreams.complication.Complication}, such as the layout
* details.
*/
@Subcomponent(modules = {
DreamWeatherComplicationComponent.DreamWeatherComplicationModule.class,
})
@DreamWeatherComplicationComponent.DreamWeatherComplicationScope
public interface DreamWeatherComplicationComponent {
/**
* Creates {@link DreamWeatherViewHolder}.
*/
DreamWeatherViewHolder getViewHolder();
@Documented
@Retention(RUNTIME)
@Scope
@interface DreamWeatherComplicationScope {
}
/**
* Generates {@link DreamWeatherComplicationComponent}.
*/
@Subcomponent.Factory
interface Factory {
DreamWeatherComplicationComponent create();
}
/**
* Scoped values for {@link DreamWeatherComplicationComponent}.
*/
@Module
interface DreamWeatherComplicationModule {
String DREAM_WEATHER_COMPLICATION_VIEW = "weather_complication_view";
String DREAM_WEATHER_COMPLICATION_LAYOUT_PARAMS =
"weather_complication_layout_params";
// Order weight of insert into parent container
int INSERT_ORDER_WEIGHT = 1;
/**
* Provides the complication view.
*/
@Provides
@DreamWeatherComplicationScope
@Named(DREAM_WEATHER_COMPLICATION_VIEW)
static TextView provideComplicationView(LayoutInflater layoutInflater) {
return Preconditions.checkNotNull((TextView)
layoutInflater.inflate(R.layout.dream_overlay_complication_weather,
null, false),
"R.layout.dream_overlay_complication_weather did not properly inflated");
}
/**
* Provides the layout parameters for the complication view.
*/
@Provides
@DreamWeatherComplicationScope
@Named(DREAM_WEATHER_COMPLICATION_LAYOUT_PARAMS)
static ComplicationLayoutParams provideLayoutParams() {
return new ComplicationLayoutParams(0,
ViewGroup.LayoutParams.WRAP_CONTENT,
ComplicationLayoutParams.POSITION_BOTTOM
| ComplicationLayoutParams.POSITION_START,
ComplicationLayoutParams.DIRECTION_END,
INSERT_ORDER_WEIGHT,
true);
}
}
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright (C) 2022 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.dreams.complication.dagger;
import com.android.systemui.dagger.SystemUIBinder;
import dagger.Module;
/**
* Module for all components with corresponding dream layer complications registered in
* {@link SystemUIBinder}.
*/
@Module(subcomponents = {
DreamClockTimeComplicationComponent.class,
DreamClockDateComplicationComponent.class,
DreamWeatherComplicationComponent.class,
})
public interface RegisteredComplicationsModule {
}

View File

@@ -16,6 +16,7 @@
package com.android.systemui.dreams.dagger;
import com.android.systemui.dreams.complication.dagger.RegisteredComplicationsModule;
import com.android.systemui.dreams.touch.dagger.DreamTouchModule;
import dagger.Module;
@@ -25,6 +26,7 @@ import dagger.Module;
*/
@Module(includes = {
DreamTouchModule.class,
RegisteredComplicationsModule.class,
},
subcomponents = {
DreamOverlayComponent.class,

View File

@@ -0,0 +1,66 @@
/*
* Copyright (C) 2022 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.dreams.complication;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import android.content.Context;
import android.testing.AndroidTestingRunner;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dreams.DreamOverlayStateController;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@SmallTest
@RunWith(AndroidTestingRunner.class)
public class DreamClockDateComplicationTest extends SysuiTestCase {
@SuppressWarnings("HidingField")
@Mock
private Context mContext;
@Mock
private DreamOverlayStateController mDreamOverlayStateController;
@Mock
private DreamClockDateComplication mComplication;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
/**
* Ensures {@link DreamClockDateComplication} is registered.
*/
@Test
public void testComplicationAdded() {
final DreamClockDateComplication.Registrant registrant =
new DreamClockDateComplication.Registrant(
mContext,
mDreamOverlayStateController,
mComplication);
registrant.start();
verify(mDreamOverlayStateController).addComplication(eq(mComplication));
}
}

View File

@@ -0,0 +1,66 @@
/*
* Copyright (C) 2022 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.dreams.complication;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import android.content.Context;
import android.testing.AndroidTestingRunner;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dreams.DreamOverlayStateController;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@SmallTest
@RunWith(AndroidTestingRunner.class)
public class DreamClockTimeComplicationTest extends SysuiTestCase {
@SuppressWarnings("HidingField")
@Mock
private Context mContext;
@Mock
private DreamOverlayStateController mDreamOverlayStateController;
@Mock
private DreamClockTimeComplication mComplication;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
/**
* Ensures {@link DreamClockTimeComplication} is registered.
*/
@Test
public void testComplicationAdded() {
final DreamClockTimeComplication.Registrant registrant =
new DreamClockTimeComplication.Registrant(
mContext,
mDreamOverlayStateController,
mComplication);
registrant.start();
verify(mDreamOverlayStateController).addComplication(eq(mComplication));
}
}

View File

@@ -0,0 +1,79 @@
/*
* Copyright (C) 2022 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.dreams.complication;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.testing.AndroidTestingRunner;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dreams.DreamOverlayStateController;
import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@SmallTest
@RunWith(AndroidTestingRunner.class)
public class DreamWeatherComplicationTest extends SysuiTestCase {
@SuppressWarnings("HidingField")
@Mock
private Context mContext;
@Mock
private LockscreenSmartspaceController mSmartspaceController;
@Mock
private DreamOverlayStateController mDreamOverlayStateController;
@Mock
private DreamWeatherComplication mComplication;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
/**
* Ensures {@link DreamWeatherComplication} is only registered when it is available.
*/
@Test
public void testComplicationAvailability() {
when(mSmartspaceController.isEnabled()).thenReturn(false);
final DreamWeatherComplication.Registrant registrant =
new DreamWeatherComplication.Registrant(
mContext,
mSmartspaceController,
mDreamOverlayStateController,
mComplication);
registrant.start();
verify(mDreamOverlayStateController, never()).addComplication(any());
when(mSmartspaceController.isEnabled()).thenReturn(true);
registrant.start();
verify(mDreamOverlayStateController).addComplication(eq(mComplication));
}
}