1 /* 2 * Copyright 2014, 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.android.managedprovisioning.common; 18 19 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.VIEW_UNKNOWN; 20 import static com.android.managedprovisioning.provisioning.Constants.LOCK_TO_PORTRAIT_MODE; 21 22 import android.app.Activity; 23 import android.app.DialogFragment; 24 import android.app.Fragment; 25 import android.app.FragmentManager; 26 import android.app.FragmentTransaction; 27 import android.content.pm.ActivityInfo; 28 import android.content.res.Configuration; 29 import android.os.Bundle; 30 31 import androidx.annotation.NonNull; 32 import androidx.annotation.VisibleForTesting; 33 import androidx.appcompat.app.AppCompatActivity; 34 import androidx.appcompat.app.AppCompatDelegate; 35 36 import com.android.managedprovisioning.ManagedProvisioningBaseApplication; 37 import com.android.managedprovisioning.ManagedProvisioningScreens; 38 import com.android.managedprovisioning.R; 39 import com.android.managedprovisioning.analytics.MetricsWriterFactory; 40 import com.android.managedprovisioning.analytics.ProvisioningAnalyticsTracker; 41 import com.android.managedprovisioning.analytics.TimeLogger; 42 import com.android.managedprovisioning.common.ThemeHelper.DefaultNightModeChecker; 43 import com.android.managedprovisioning.common.ThemeHelper.DefaultSetupWizardBridge; 44 import com.android.managedprovisioning.preprovisioning.EncryptionController; 45 46 /** 47 * Base class for setting up the layout. 48 */ 49 public abstract class SetupLayoutActivity extends AppCompatActivity { 50 protected final Utils mUtils; 51 protected final SettingsFacade mSettingsFacade; 52 private final ThemeHelper mThemeHelper; 53 private final TransitionHelper mTransitionHelper; 54 private TimeLogger mTimeLogger; 55 SetupLayoutActivity()56 public SetupLayoutActivity() { 57 this(new Utils(), new SettingsFacade(), 58 new ThemeHelper(new DefaultNightModeChecker(), new DefaultSetupWizardBridge())); 59 } 60 61 @VisibleForTesting SetupLayoutActivity( Utils utils, SettingsFacade settingsFacade, ThemeHelper themeHelper)62 protected SetupLayoutActivity( 63 Utils utils, SettingsFacade settingsFacade, ThemeHelper themeHelper) { 64 mUtils = utils; 65 mSettingsFacade = settingsFacade; 66 mThemeHelper = themeHelper; 67 // TODO(b/183036855): Add dependency injection in ManagedProvisioning 68 mTransitionHelper = new TransitionHelper(); 69 } 70 71 @Override onCreate(Bundle savedInstanceState)72 protected void onCreate(Bundle savedInstanceState) { 73 if (!isWaitingScreen()) { 74 mTransitionHelper.applyContentScreenTransitions(this); 75 } 76 updateDefaultNightMode(); 77 setTheme(mThemeHelper.inferThemeResId(this, getIntent())); 78 if (shouldSetupDynamicColors()) { 79 mThemeHelper.setupDynamicColors(this); 80 } 81 super.onCreate(savedInstanceState); 82 mTimeLogger = new TimeLogger(this, getMetricsCategory()); 83 mTimeLogger.start(); 84 85 // lock orientation to portrait on phones if necessary 86 if (LOCK_TO_PORTRAIT_MODE && getResources().getBoolean(R.bool.lock_to_portrait)) { 87 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 88 } 89 logMetrics(); 90 } 91 shouldSetupDynamicColors()92 protected boolean shouldSetupDynamicColors() { 93 return true; 94 } 95 96 @Override onConfigurationChanged(@onNull Configuration newConfig)97 public void onConfigurationChanged(@NonNull Configuration newConfig) { 98 super.onConfigurationChanged(newConfig); 99 updateDefaultNightMode(); 100 } 101 updateDefaultNightMode()102 private void updateDefaultNightMode() { 103 int nightMode = mThemeHelper.getDefaultNightMode(this, getIntent()); 104 AppCompatDelegate delegate = AppCompatDelegate.create(this, /* callback= */ null); 105 delegate.setLocalNightMode(nightMode); 106 } 107 108 @Override onResume()109 protected void onResume() { 110 super.onResume(); 111 if (isWaitingScreen()) { 112 mTransitionHelper.applyWaitingScreenTransitions(this); 113 } 114 } 115 logMetrics()116 private void logMetrics() { 117 // TODO(b/183036855): Add dependency injection in ManagedProvisioning 118 ProvisioningAnalyticsTracker analyticsTracker = new ProvisioningAnalyticsTracker( 119 MetricsWriterFactory.getMetricsWriter(this, new SettingsFacade()), 120 new ManagedProvisioningSharedPreferences(this)); 121 final int orientation = getResources().getConfiguration().orientation; 122 analyticsTracker.logIsLandscape( 123 orientation == Configuration.ORIENTATION_LANDSCAPE, 124 getLocalClassName()); 125 } 126 127 @Override onDestroy()128 public void onDestroy() { 129 mTimeLogger.stop(); 130 super.onDestroy(); 131 } 132 getMetricsCategory()133 protected int getMetricsCategory() { 134 return VIEW_UNKNOWN; 135 } 136 getUtils()137 protected Utils getUtils() { 138 return mUtils; 139 } 140 getThemeHelper()141 protected ThemeHelper getThemeHelper() { 142 return mThemeHelper; 143 } 144 getTransitionHelper()145 protected TransitionHelper getTransitionHelper() { 146 return mTransitionHelper; 147 } 148 getBaseApplication()149 private ManagedProvisioningBaseApplication getBaseApplication() { 150 return ((ManagedProvisioningBaseApplication) getApplication()); 151 } 152 getActivityForScreen(ManagedProvisioningScreens screen)153 protected Class<? extends Activity> getActivityForScreen(ManagedProvisioningScreens screen) { 154 return getBaseApplication().getActivityClassForScreen(screen); 155 } 156 getEncryptionController()157 protected EncryptionController getEncryptionController() { 158 return getBaseApplication().getEncryptionController(); 159 } 160 161 /** 162 * Whether the current screen is a waiting screen. 163 * 164 * <p>A waiting screen is a screen that shows a spinner and not content. 165 */ isWaitingScreen()166 protected boolean isWaitingScreen() { 167 return false; 168 } 169 170 /** 171 * Constructs and shows a {@link DialogFragment} unless it is already displayed. 172 * @param dialogBuilder Lightweight builder, that it is inexpensive to discard it if dialog 173 * already shown. 174 * @param tag The tag for this dialog, as per {@link FragmentTransaction#add(Fragment, String)}. 175 */ showDialog(DialogBuilder dialogBuilder, String tag)176 protected void showDialog(DialogBuilder dialogBuilder, String tag) { 177 FragmentManager fragmentManager = getFragmentManager(); 178 if (!isDialogAdded(tag)) { 179 dialogBuilder.build().show(fragmentManager, tag); 180 } 181 } 182 183 /** 184 * Checks whether the {@link DialogFragment} associated with the given tag is currently showing. 185 * @param tag The tag for this dialog. 186 */ isDialogAdded(String tag)187 protected boolean isDialogAdded(String tag) { 188 Fragment fragment = getFragmentManager().findFragmentByTag(tag); 189 return (fragment != null) && (fragment.isAdded()); 190 } 191 }