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