| Setup Wizard Team | 8ccc9e6 | 2018-11-28 13:33:48 +0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2018 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | package com.google.android.setupcompat; |
| 18 | |
| Setup Wizard Team | 8ccc9e6 | 2018-11-28 13:33:48 +0800 | [diff] [blame] | 19 | import android.app.Activity; |
| 20 | import android.content.Context; |
| Setup Wizard Team | 8ccc9e6 | 2018-11-28 13:33:48 +0800 | [diff] [blame] | 21 | import android.content.res.TypedArray; |
| Setup Wizard Team | de9b52a | 2019-04-01 10:27:47 +0800 | [diff] [blame] | 22 | import android.os.Build; |
| Setup Wizard Team | 1ed3073 | 2019-03-14 10:00:10 +0800 | [diff] [blame] | 23 | import android.os.Build.VERSION; |
| Setup Wizard Team | 8ccc9e6 | 2018-11-28 13:33:48 +0800 | [diff] [blame] | 24 | import android.os.Build.VERSION_CODES; |
| Setup Wizard Team | 1d79d00 | 2018-12-13 14:30:13 +0800 | [diff] [blame] | 25 | import android.os.PersistableBundle; |
| Setup Wizard Team | 8ccc9e6 | 2018-11-28 13:33:48 +0800 | [diff] [blame] | 26 | import android.util.AttributeSet; |
| 27 | import android.view.LayoutInflater; |
| 28 | import android.view.View; |
| 29 | import android.view.ViewGroup; |
| Setup Wizard Team | 55addcd | 2022-01-06 23:50:39 +0800 | [diff] [blame] | 30 | import android.view.ViewTreeObserver; |
| Setup Wizard Team | 8ccc9e6 | 2018-11-28 13:33:48 +0800 | [diff] [blame] | 31 | import android.view.WindowManager; |
| Setup Wizard Team | 55addcd | 2022-01-06 23:50:39 +0800 | [diff] [blame] | 32 | import androidx.annotation.VisibleForTesting; |
| 33 | import com.google.android.setupcompat.internal.FocusChangedMetricHelper; |
| Setup Wizard Team | de9b52a | 2019-04-01 10:27:47 +0800 | [diff] [blame] | 34 | import com.google.android.setupcompat.internal.LifecycleFragment; |
| Setup Wizard Team | d6fc4af | 2019-12-31 20:58:11 +0800 | [diff] [blame] | 35 | import com.google.android.setupcompat.internal.PersistableBundles; |
| Setup Wizard Team | 55addcd | 2022-01-06 23:50:39 +0800 | [diff] [blame] | 36 | import com.google.android.setupcompat.internal.SetupCompatServiceInvoker; |
| Maurice Lam | c452932 | 2019-02-14 22:04:56 +0000 | [diff] [blame] | 37 | import com.google.android.setupcompat.internal.TemplateLayout; |
| Setup Wizard Team | 1d79d00 | 2018-12-13 14:30:13 +0800 | [diff] [blame] | 38 | import com.google.android.setupcompat.logging.CustomEvent; |
| Setup Wizard Team | 4f5bbf4 | 2023-12-20 03:05:46 +0000 | [diff] [blame] | 39 | import com.google.android.setupcompat.logging.LoggingObserver; |
| 40 | import com.google.android.setupcompat.logging.LoggingObserver.SetupCompatUiEvent.LayoutInflatedEvent; |
| Setup Wizard Team | 1d79d00 | 2018-12-13 14:30:13 +0800 | [diff] [blame] | 41 | import com.google.android.setupcompat.logging.MetricKey; |
| 42 | import com.google.android.setupcompat.logging.SetupMetricsLogger; |
| Setup Wizard Team | 1ed3073 | 2019-03-14 10:00:10 +0800 | [diff] [blame] | 43 | import com.google.android.setupcompat.partnerconfig.PartnerConfigHelper; |
| Setup Wizard Team | d41e3be | 2019-01-17 16:07:58 +0800 | [diff] [blame] | 44 | import com.google.android.setupcompat.template.FooterBarMixin; |
| 45 | import com.google.android.setupcompat.template.FooterButton; |
| Setup Wizard Team | 8ccc9e6 | 2018-11-28 13:33:48 +0800 | [diff] [blame] | 46 | import com.google.android.setupcompat.template.StatusBarMixin; |
| 47 | import com.google.android.setupcompat.template.SystemNavBarMixin; |
| Setup Wizard Team | 8a37aa8 | 2021-04-26 10:01:19 +0800 | [diff] [blame] | 48 | import com.google.android.setupcompat.util.BuildCompatUtils; |
| Setup Wizard Team | f513dd2 | 2021-06-10 15:49:36 +0800 | [diff] [blame] | 49 | import com.google.android.setupcompat.util.Logger; |
| Setup Wizard Team | 8ccc9e6 | 2018-11-28 13:33:48 +0800 | [diff] [blame] | 50 | import com.google.android.setupcompat.util.WizardManagerHelper; |
| Setup Wizard Team | 0d3126a | 2022-04-27 09:03:55 +0800 | [diff] [blame] | 51 | import com.google.errorprone.annotations.CanIgnoreReturnValue; |
| Setup Wizard Team | 8ccc9e6 | 2018-11-28 13:33:48 +0800 | [diff] [blame] | 52 | |
| 53 | /** A templatization layout with consistent style used in Setup Wizard or app itself. */ |
| 54 | public class PartnerCustomizationLayout extends TemplateLayout { |
| Setup Wizard Team | f513dd2 | 2021-06-10 15:49:36 +0800 | [diff] [blame] | 55 | |
| 56 | private static final Logger LOG = new Logger("PartnerCustomizationLayout"); |
| Setup Wizard Team | 8ccc9e6 | 2018-11-28 13:33:48 +0800 | [diff] [blame] | 57 | |
| Setup Wizard Team | 67e7fef | 2019-03-23 08:06:48 +0800 | [diff] [blame] | 58 | /** |
| 59 | * Attribute indicating whether usage of partner theme resources is allowed. This corresponds to |
| 60 | * the {@code app:sucUsePartnerResource} XML attribute. Note that when running in setup wizard, |
| 61 | * this is always overridden to true. |
| 62 | */ |
| Setup Wizard Team | de9b52a | 2019-04-01 10:27:47 +0800 | [diff] [blame] | 63 | private boolean usePartnerResourceAttr; |
| Setup Wizard Team | 1ed3073 | 2019-03-14 10:00:10 +0800 | [diff] [blame] | 64 | |
| Setup Wizard Team | 8a37aa8 | 2021-04-26 10:01:19 +0800 | [diff] [blame] | 65 | /** |
| 66 | * Attribute indicating whether using full dynamic colors or not. This corresponds to the {@code |
| 67 | * app:sucFullDynamicColor} XML attribute. |
| 68 | */ |
| 69 | private boolean useFullDynamicColorAttr; |
| 70 | |
| 71 | /** |
| 72 | * Attribute indicating whether usage of dynamic is allowed. This corresponds to the existence of |
| 73 | * {@code app:sucFullDynamicColor} XML attribute. |
| 74 | */ |
| 75 | private boolean useDynamicColor; |
| 76 | |
| Setup Wizard Team | 8ccc9e6 | 2018-11-28 13:33:48 +0800 | [diff] [blame] | 77 | private Activity activity; |
| 78 | |
| David Liu | 534db6a | 2023-02-15 06:55:44 +0000 | [diff] [blame] | 79 | private PersistableBundle layoutTypeBundle; |
| 80 | |
| Setup Wizard Team | 0d3126a | 2022-04-27 09:03:55 +0800 | [diff] [blame] | 81 | @CanIgnoreReturnValue |
| Setup Wizard Team | 8ccc9e6 | 2018-11-28 13:33:48 +0800 | [diff] [blame] | 82 | public PartnerCustomizationLayout(Context context) { |
| 83 | this(context, 0, 0); |
| 84 | } |
| 85 | |
| Setup Wizard Team | 0d3126a | 2022-04-27 09:03:55 +0800 | [diff] [blame] | 86 | @CanIgnoreReturnValue |
| Setup Wizard Team | 8ccc9e6 | 2018-11-28 13:33:48 +0800 | [diff] [blame] | 87 | public PartnerCustomizationLayout(Context context, int template) { |
| 88 | this(context, template, 0); |
| 89 | } |
| 90 | |
| Setup Wizard Team | 0d3126a | 2022-04-27 09:03:55 +0800 | [diff] [blame] | 91 | @CanIgnoreReturnValue |
| Setup Wizard Team | 8ccc9e6 | 2018-11-28 13:33:48 +0800 | [diff] [blame] | 92 | public PartnerCustomizationLayout(Context context, int template, int containerId) { |
| 93 | super(context, template, containerId); |
| 94 | init(null, R.attr.sucLayoutTheme); |
| 95 | } |
| 96 | |
| Setup Wizard Team | 0d3126a | 2022-04-27 09:03:55 +0800 | [diff] [blame] | 97 | @CanIgnoreReturnValue |
| Setup Wizard Team | 8ccc9e6 | 2018-11-28 13:33:48 +0800 | [diff] [blame] | 98 | public PartnerCustomizationLayout(Context context, AttributeSet attrs) { |
| 99 | super(context, attrs); |
| 100 | init(attrs, R.attr.sucLayoutTheme); |
| 101 | } |
| 102 | |
| Setup Wizard Team | 0d3126a | 2022-04-27 09:03:55 +0800 | [diff] [blame] | 103 | @CanIgnoreReturnValue |
| Setup Wizard Team | 8ccc9e6 | 2018-11-28 13:33:48 +0800 | [diff] [blame] | 104 | public PartnerCustomizationLayout(Context context, AttributeSet attrs, int defStyleAttr) { |
| 105 | super(context, attrs, defStyleAttr); |
| 106 | init(attrs, defStyleAttr); |
| 107 | } |
| 108 | |
| David Liu | 534db6a | 2023-02-15 06:55:44 +0000 | [diff] [blame] | 109 | @VisibleForTesting |
| 110 | final ViewTreeObserver.OnWindowFocusChangeListener windowFocusChangeListener = |
| 111 | this::onFocusChanged; |
| 112 | |
| Setup Wizard Team | 8ccc9e6 | 2018-11-28 13:33:48 +0800 | [diff] [blame] | 113 | private void init(AttributeSet attrs, int defStyleAttr) { |
| Setup Wizard Team | 261f8b4 | 2021-03-04 09:18:37 +0800 | [diff] [blame] | 114 | if (isInEditMode()) { |
| 115 | return; |
| 116 | } |
| Setup Wizard Team | 8ccc9e6 | 2018-11-28 13:33:48 +0800 | [diff] [blame] | 117 | |
| 118 | TypedArray a = |
| 119 | getContext() |
| 120 | .obtainStyledAttributes( |
| 121 | attrs, R.styleable.SucPartnerCustomizationLayout, defStyleAttr, 0); |
| 122 | |
| Setup Wizard Team | 8ccc9e6 | 2018-11-28 13:33:48 +0800 | [diff] [blame] | 123 | boolean layoutFullscreen = |
| 124 | a.getBoolean(R.styleable.SucPartnerCustomizationLayout_sucLayoutFullscreen, true); |
| Setup Wizard Team | ff4fecb | 2018-12-19 11:31:37 +0800 | [diff] [blame] | 125 | |
| Setup Wizard Team | 8ccc9e6 | 2018-11-28 13:33:48 +0800 | [diff] [blame] | 126 | a.recycle(); |
| 127 | |
| Setup Wizard Team | 1ed3073 | 2019-03-14 10:00:10 +0800 | [diff] [blame] | 128 | if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP && layoutFullscreen) { |
| Setup Wizard Team | 8ccc9e6 | 2018-11-28 13:33:48 +0800 | [diff] [blame] | 129 | setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); |
| 130 | } |
| 131 | |
| Setup Wizard Team | ff4fecb | 2018-12-19 11:31:37 +0800 | [diff] [blame] | 132 | registerMixin( |
| Setup Wizard Team | 67e7fef | 2019-03-23 08:06:48 +0800 | [diff] [blame] | 133 | StatusBarMixin.class, new StatusBarMixin(this, activity.getWindow(), attrs, defStyleAttr)); |
| 134 | registerMixin(SystemNavBarMixin.class, new SystemNavBarMixin(this, activity.getWindow())); |
| 135 | registerMixin(FooterBarMixin.class, new FooterBarMixin(this, attrs, defStyleAttr)); |
| Setup Wizard Team | ff4fecb | 2018-12-19 11:31:37 +0800 | [diff] [blame] | 136 | |
| Setup Wizard Team | 1ed3073 | 2019-03-14 10:00:10 +0800 | [diff] [blame] | 137 | getMixin(SystemNavBarMixin.class).applyPartnerCustomizations(attrs, defStyleAttr); |
| 138 | |
| Setup Wizard Team | 8ccc9e6 | 2018-11-28 13:33:48 +0800 | [diff] [blame] | 139 | // Override the FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, FLAG_TRANSLUCENT_STATUS, |
| 140 | // FLAG_TRANSLUCENT_NAVIGATION and SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN attributes of window forces |
| 141 | // showing status bar and navigation bar. |
| Setup Wizard Team | de9b52a | 2019-04-01 10:27:47 +0800 | [diff] [blame] | 142 | if (Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { |
| 143 | activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); |
| 144 | activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); |
| 145 | activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); |
| 146 | } |
| Setup Wizard Team | 8ccc9e6 | 2018-11-28 13:33:48 +0800 | [diff] [blame] | 147 | } |
| 148 | |
| 149 | @Override |
| 150 | protected View onInflateTemplate(LayoutInflater inflater, int template) { |
| 151 | if (template == 0) { |
| 152 | template = R.layout.partner_customization_layout; |
| 153 | } |
| 154 | return inflateTemplate(inflater, 0, template); |
| 155 | } |
| 156 | |
| Setup Wizard Team | de9b52a | 2019-04-01 10:27:47 +0800 | [diff] [blame] | 157 | /** |
| 158 | * {@inheritDoc} |
| 159 | * |
| 160 | * <p>This method sets all these flags before onTemplateInflated since it will be too late and get |
| 161 | * incorrect flag value on PartnerCustomizationLayout if sets them after onTemplateInflated. |
| 162 | */ |
| 163 | @Override |
| 164 | protected void onBeforeTemplateInflated(AttributeSet attrs, int defStyleAttr) { |
| 165 | |
| Setup Wizard Team | de9b52a | 2019-04-01 10:27:47 +0800 | [diff] [blame] | 166 | // Sets default value to true since this timing |
| 167 | // before PartnerCustomization members initialization |
| 168 | usePartnerResourceAttr = true; |
| 169 | |
| 170 | activity = lookupActivityFromContext(getContext()); |
| 171 | |
| Setup Wizard Team | 75de590 | 2020-09-22 20:34:53 +0800 | [diff] [blame] | 172 | boolean isSetupFlow = WizardManagerHelper.isAnySetupWizard(activity.getIntent()); |
| Setup Wizard Team | de9b52a | 2019-04-01 10:27:47 +0800 | [diff] [blame] | 173 | |
| 174 | TypedArray a = |
| 175 | getContext() |
| 176 | .obtainStyledAttributes( |
| 177 | attrs, R.styleable.SucPartnerCustomizationLayout, defStyleAttr, 0); |
| 178 | |
| 179 | if (!a.hasValue(R.styleable.SucPartnerCustomizationLayout_sucUsePartnerResource)) { |
| Setup Wizard Team | 5b6b1b3 | 2019-04-02 13:42:22 +0800 | [diff] [blame] | 180 | // TODO: Enable Log.WTF after other client already set sucUsePartnerResource. |
| Setup Wizard Team | f513dd2 | 2021-06-10 15:49:36 +0800 | [diff] [blame] | 181 | LOG.e("Attribute sucUsePartnerResource not found in " + activity.getComponentName()); |
| Setup Wizard Team | de9b52a | 2019-04-01 10:27:47 +0800 | [diff] [blame] | 182 | } |
| 183 | |
| 184 | usePartnerResourceAttr = |
| 185 | isSetupFlow |
| 186 | || a.getBoolean(R.styleable.SucPartnerCustomizationLayout_sucUsePartnerResource, true); |
| 187 | |
| Setup Wizard Team | 8a37aa8 | 2021-04-26 10:01:19 +0800 | [diff] [blame] | 188 | useDynamicColor = a.hasValue(R.styleable.SucPartnerCustomizationLayout_sucFullDynamicColor); |
| 189 | useFullDynamicColorAttr = |
| 190 | a.getBoolean(R.styleable.SucPartnerCustomizationLayout_sucFullDynamicColor, false); |
| 191 | |
| Setup Wizard Team | de9b52a | 2019-04-01 10:27:47 +0800 | [diff] [blame] | 192 | a.recycle(); |
| 193 | |
| Setup Wizard Team | f513dd2 | 2021-06-10 15:49:36 +0800 | [diff] [blame] | 194 | LOG.atDebug( |
| 195 | "activity=" |
| 196 | + activity.getClass().getSimpleName() |
| 197 | + " isSetupFlow=" |
| 198 | + isSetupFlow |
| 199 | + " enablePartnerResourceLoading=" |
| 200 | + enablePartnerResourceLoading() |
| 201 | + " usePartnerResourceAttr=" |
| 202 | + usePartnerResourceAttr |
| 203 | + " useDynamicColor=" |
| 204 | + useDynamicColor |
| 205 | + " useFullDynamicColorAttr=" |
| 206 | + useFullDynamicColorAttr); |
| Setup Wizard Team | de9b52a | 2019-04-01 10:27:47 +0800 | [diff] [blame] | 207 | } |
| 208 | |
| Setup Wizard Team | 8ccc9e6 | 2018-11-28 13:33:48 +0800 | [diff] [blame] | 209 | @Override |
| 210 | protected ViewGroup findContainer(int containerId) { |
| 211 | if (containerId == 0) { |
| 212 | containerId = R.id.suc_layout_content; |
| 213 | } |
| 214 | return super.findContainer(containerId); |
| 215 | } |
| 216 | |
| 217 | @Override |
| 218 | protected void onAttachedToWindow() { |
| 219 | super.onAttachedToWindow(); |
| Setup Wizard Team | 1d79d00 | 2018-12-13 14:30:13 +0800 | [diff] [blame] | 220 | LifecycleFragment.attachNow(activity); |
| Setup Wizard Team | aa4a4b7 | 2023-10-16 04:39:29 +0000 | [diff] [blame] | 221 | if (WizardManagerHelper.isAnySetupWizard(activity.getIntent())) { |
| Setup Wizard Team | 55addcd | 2022-01-06 23:50:39 +0800 | [diff] [blame] | 222 | getViewTreeObserver().addOnWindowFocusChangeListener(windowFocusChangeListener); |
| 223 | } |
| Setup Wizard Team | d41e3be | 2019-01-17 16:07:58 +0800 | [diff] [blame] | 224 | getMixin(FooterBarMixin.class).onAttachedToWindow(); |
| Setup Wizard Team | 1d79d00 | 2018-12-13 14:30:13 +0800 | [diff] [blame] | 225 | } |
| 226 | |
| 227 | @Override |
| 228 | protected void onDetachedFromWindow() { |
| 229 | super.onDetachedFromWindow(); |
| Setup Wizard Team | 55addcd | 2022-01-06 23:50:39 +0800 | [diff] [blame] | 230 | if (VERSION.SDK_INT >= Build.VERSION_CODES.Q |
| Setup Wizard Team | de9b52a | 2019-04-01 10:27:47 +0800 | [diff] [blame] | 231 | && WizardManagerHelper.isAnySetupWizard(activity.getIntent())) { |
| Setup Wizard Team | d41e3be | 2019-01-17 16:07:58 +0800 | [diff] [blame] | 232 | FooterBarMixin footerBarMixin = getMixin(FooterBarMixin.class); |
| 233 | footerBarMixin.onDetachedFromWindow(); |
| 234 | FooterButton primaryButton = footerBarMixin.getPrimaryButton(); |
| 235 | FooterButton secondaryButton = footerBarMixin.getSecondaryButton(); |
| 236 | PersistableBundle primaryButtonMetrics = |
| 237 | primaryButton != null |
| 238 | ? primaryButton.getMetrics("PrimaryFooterButton") |
| 239 | : PersistableBundle.EMPTY; |
| 240 | PersistableBundle secondaryButtonMetrics = |
| 241 | secondaryButton != null |
| 242 | ? secondaryButton.getMetrics("SecondaryFooterButton") |
| 243 | : PersistableBundle.EMPTY; |
| 244 | |
| David Liu | 534db6a | 2023-02-15 06:55:44 +0000 | [diff] [blame] | 245 | PersistableBundle layoutTypeMetrics = |
| 246 | (layoutTypeBundle != null) ? layoutTypeBundle : PersistableBundle.EMPTY; |
| 247 | |
| Setup Wizard Team | d6fc4af | 2019-12-31 20:58:11 +0800 | [diff] [blame] | 248 | PersistableBundle persistableBundle = |
| 249 | PersistableBundles.mergeBundles( |
| David Liu | 534db6a | 2023-02-15 06:55:44 +0000 | [diff] [blame] | 250 | footerBarMixin.getLoggingMetrics(), |
| 251 | primaryButtonMetrics, |
| 252 | secondaryButtonMetrics, |
| 253 | layoutTypeMetrics); |
| Setup Wizard Team | d41e3be | 2019-01-17 16:07:58 +0800 | [diff] [blame] | 254 | |
| Setup Wizard Team | 1d79d00 | 2018-12-13 14:30:13 +0800 | [diff] [blame] | 255 | SetupMetricsLogger.logCustomEvent( |
| 256 | getContext(), |
| Setup Wizard Team | 24bb1e2 | 2019-11-08 15:22:51 +0800 | [diff] [blame] | 257 | CustomEvent.create(MetricKey.get("SetupCompatMetrics", activity), persistableBundle)); |
| Setup Wizard Team | 1d79d00 | 2018-12-13 14:30:13 +0800 | [diff] [blame] | 258 | } |
| Setup Wizard Team | aa4a4b7 | 2023-10-16 04:39:29 +0000 | [diff] [blame] | 259 | getViewTreeObserver().removeOnWindowFocusChangeListener(windowFocusChangeListener); |
| Setup Wizard Team | 8ccc9e6 | 2018-11-28 13:33:48 +0800 | [diff] [blame] | 260 | } |
| 261 | |
| David Liu | 534db6a | 2023-02-15 06:55:44 +0000 | [diff] [blame] | 262 | /** |
| Setup Wizard Team | 4f5bbf4 | 2023-12-20 03:05:46 +0000 | [diff] [blame] | 263 | * PartnerCustomizationLayout is a template layout for different type of GlifLayout. This method |
| 264 | * allows each type of layout to report its "GlifLayoutType". |
| David Liu | 534db6a | 2023-02-15 06:55:44 +0000 | [diff] [blame] | 265 | */ |
| 266 | public void setLayoutTypeMetrics(PersistableBundle bundle) { |
| 267 | this.layoutTypeBundle = bundle; |
| 268 | } |
| 269 | |
| 270 | /** Returns a {@link PersistableBundle} contains key "GlifLayoutType". */ |
| 271 | @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED) |
| 272 | public PersistableBundle getLayoutTypeMetrics() { |
| 273 | return this.layoutTypeBundle; |
| 274 | } |
| 275 | |
| Setup Wizard Team | 642e096 | 2020-12-30 19:23:06 +0800 | [diff] [blame] | 276 | public static Activity lookupActivityFromContext(Context context) { |
| Setup Wizard Team | aa4a4b7 | 2023-10-16 04:39:29 +0000 | [diff] [blame] | 277 | return PartnerConfigHelper.lookupActivityFromContext(context); |
| Setup Wizard Team | 8ccc9e6 | 2018-11-28 13:33:48 +0800 | [diff] [blame] | 278 | } |
| 279 | |
| 280 | /** |
| Setup Wizard Team | 67e7fef | 2019-03-23 08:06:48 +0800 | [diff] [blame] | 281 | * Returns true if partner resource loading is enabled. If true, and other necessary conditions |
| 282 | * for loading theme attributes are met, this layout will use customized theme attributes from OEM |
| 283 | * overlays. This is intended to be used with flag-based development, to allow a flag to control |
| 284 | * the rollout of partner resource loading. |
| Setup Wizard Team | d41e3be | 2019-01-17 16:07:58 +0800 | [diff] [blame] | 285 | */ |
| Setup Wizard Team | 67e7fef | 2019-03-23 08:06:48 +0800 | [diff] [blame] | 286 | protected boolean enablePartnerResourceLoading() { |
| Setup Wizard Team | d41e3be | 2019-01-17 16:07:58 +0800 | [diff] [blame] | 287 | return true; |
| 288 | } |
| 289 | |
| Setup Wizard Team | 1ed3073 | 2019-03-14 10:00:10 +0800 | [diff] [blame] | 290 | /** Returns if the current layout/activity applies partner customized configurations or not. */ |
| Setup Wizard Team | 67e7fef | 2019-03-23 08:06:48 +0800 | [diff] [blame] | 291 | public boolean shouldApplyPartnerResource() { |
| 292 | if (!enablePartnerResourceLoading()) { |
| 293 | return false; |
| 294 | } |
| 295 | if (!usePartnerResourceAttr) { |
| 296 | return false; |
| 297 | } |
| Setup Wizard Team | 3266cd8 | 2019-05-09 19:31:02 +0800 | [diff] [blame] | 298 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { |
| Setup Wizard Team | 67e7fef | 2019-03-23 08:06:48 +0800 | [diff] [blame] | 299 | return false; |
| 300 | } |
| 301 | if (!PartnerConfigHelper.get(getContext()).isAvailable()) { |
| 302 | return false; |
| 303 | } |
| 304 | return true; |
| Setup Wizard Team | 1ed3073 | 2019-03-14 10:00:10 +0800 | [diff] [blame] | 305 | } |
| Setup Wizard Team | 8a37aa8 | 2021-04-26 10:01:19 +0800 | [diff] [blame] | 306 | |
| 307 | /** |
| 308 | * Returns {@code true} if the current layout/activity applies dynamic color. Otherwise, returns |
| 309 | * {@code false}. |
| 310 | */ |
| 311 | public boolean shouldApplyDynamicColor() { |
| Pasty Chang | fc90bfe | 2024-10-07 12:01:17 +0000 | [diff] [blame^] | 312 | if (!PartnerConfigHelper.isSetupWizardDynamicColorEnabled(getContext())) { |
| 313 | return false; |
| 314 | } |
| 315 | |
| Setup Wizard Team | 8a37aa8 | 2021-04-26 10:01:19 +0800 | [diff] [blame] | 316 | if (!useDynamicColor) { |
| 317 | return false; |
| 318 | } |
| 319 | if (!BuildCompatUtils.isAtLeastS()) { |
| 320 | return false; |
| 321 | } |
| 322 | if (!PartnerConfigHelper.get(getContext()).isAvailable()) { |
| 323 | return false; |
| 324 | } |
| 325 | return true; |
| 326 | } |
| 327 | |
| 328 | /** |
| 329 | * Returns {@code true} if the current layout/activity applies full dynamic color. Otherwise, |
| Pasty Chang | fc90bfe | 2024-10-07 12:01:17 +0000 | [diff] [blame^] | 330 | * returns {@code false}. This method combines the result of {@link #shouldApplyDynamicColor()}, |
| 331 | * the value of the {@code app:sucFullDynamicColor}, and the result of {@link |
| 332 | * PartnerConfigHelper#isSetupWizardFullDynamicColorEnabled(Context)}. |
| Setup Wizard Team | 8a37aa8 | 2021-04-26 10:01:19 +0800 | [diff] [blame] | 333 | */ |
| 334 | public boolean useFullDynamicColor() { |
| Pasty Chang | fc90bfe | 2024-10-07 12:01:17 +0000 | [diff] [blame^] | 335 | return shouldApplyDynamicColor() |
| 336 | && (useFullDynamicColorAttr |
| 337 | || PartnerConfigHelper.isSetupWizardFullDynamicColorEnabled(getContext())); |
| Setup Wizard Team | 8a37aa8 | 2021-04-26 10:01:19 +0800 | [diff] [blame] | 338 | } |
| Setup Wizard Team | 55addcd | 2022-01-06 23:50:39 +0800 | [diff] [blame] | 339 | |
| 340 | /** |
| Pasty Chang | fc90bfe | 2024-10-07 12:01:17 +0000 | [diff] [blame^] | 341 | * Sets a logging observer for {@link FooterBarMixin}. The logging observer is used to log UI |
| 342 | * events (e.g. page impressions and button clicks) on the layout and footer bar buttons. |
| Setup Wizard Team | 4f5bbf4 | 2023-12-20 03:05:46 +0000 | [diff] [blame] | 343 | */ |
| 344 | public void setLoggingObserver(LoggingObserver loggingObserver) { |
| Setup Wizard Team | 4f5bbf4 | 2023-12-20 03:05:46 +0000 | [diff] [blame] | 345 | loggingObserver.log(new LayoutInflatedEvent(this)); |
| Pasty Chang | fc90bfe | 2024-10-07 12:01:17 +0000 | [diff] [blame^] | 346 | getMixin(FooterBarMixin.class).setLoggingObserver(loggingObserver); |
| Setup Wizard Team | 4f5bbf4 | 2023-12-20 03:05:46 +0000 | [diff] [blame] | 347 | } |
| 348 | |
| 349 | /** |
| Setup Wizard Team | 55addcd | 2022-01-06 23:50:39 +0800 | [diff] [blame] | 350 | * Invoke the method onFocusStatusChanged when onWindowFocusChangeListener receive onFocusChanged. |
| 351 | */ |
| 352 | private void onFocusChanged(boolean hasFocus) { |
| 353 | SetupCompatServiceInvoker.get(getContext()) |
| 354 | .onFocusStatusChanged( |
| 355 | FocusChangedMetricHelper.getScreenName(activity), |
| 356 | FocusChangedMetricHelper.getExtraBundle( |
| 357 | activity, PartnerCustomizationLayout.this, hasFocus)); |
| 358 | } |
| Setup Wizard Team | 8ccc9e6 | 2018-11-28 13:33:48 +0800 | [diff] [blame] | 359 | } |