1 /* 2 * Copyright 2019, 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.finalization; 18 19 import static android.app.admin.DevicePolicyManager.ACTION_ADMIN_POLICY_COMPLIANCE; 20 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE; 21 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE; 22 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE; 23 24 import static com.android.managedprovisioning.TestUtils.createTestAdminExtras; 25 26 import static com.google.common.truth.Truth.assertThat; 27 28 import static org.mockito.ArgumentMatchers.anyString; 29 import static org.mockito.Matchers.any; 30 import static org.mockito.Matchers.anyInt; 31 import static org.mockito.Matchers.eq; 32 import static org.mockito.Mockito.mock; 33 import static org.mockito.Mockito.never; 34 import static org.mockito.Mockito.times; 35 import static org.mockito.Mockito.verify; 36 import static org.mockito.Mockito.verifyNoMoreInteractions; 37 import static org.mockito.Mockito.verifyZeroInteractions; 38 import static org.mockito.Mockito.when; 39 40 import android.accounts.Account; 41 import android.app.Activity; 42 import android.app.admin.DevicePolicyManager; 43 import android.content.ComponentName; 44 import android.content.Context; 45 import android.content.Intent; 46 import android.content.ServiceConnection; 47 import android.content.SharedPreferences; 48 import android.content.pm.PackageManager; 49 import android.os.Bundle; 50 import android.os.PersistableBundle; 51 import android.os.UserHandle; 52 import android.os.UserManager; 53 import android.test.AndroidTestCase; 54 55 import androidx.test.InstrumentationRegistry; 56 import androidx.test.filters.SmallTest; 57 58 import com.android.managedprovisioning.TestUtils; 59 import com.android.managedprovisioning.analytics.DeferredMetricsReader; 60 import com.android.managedprovisioning.analytics.ProvisioningAnalyticsTracker; 61 import com.android.managedprovisioning.common.NotificationHelper; 62 import com.android.managedprovisioning.common.PolicyComplianceUtils; 63 import com.android.managedprovisioning.common.SettingsFacade; 64 import com.android.managedprovisioning.common.TransitionHelper; 65 import com.android.managedprovisioning.common.Utils; 66 import com.android.managedprovisioning.model.ProvisioningParams; 67 68 import org.mockito.ArgumentCaptor; 69 import org.mockito.Mock; 70 import org.mockito.MockitoAnnotations; 71 72 /** 73 * Unit tests for {@link FinalizationInsideSuwControllerLogic}. 74 */ 75 public class FinalizationInsideSuwControllerTest extends AndroidTestCase { 76 private static final UserHandle MANAGED_PROFILE_USER_HANDLE = UserHandle.of(123); 77 private static final String TEST_MDM_PACKAGE_NAME = "mdm.package.name"; 78 private static final String TEST_MDM_ADMIN_RECEIVER = TEST_MDM_PACKAGE_NAME + ".AdminReceiver"; 79 private static final ComponentName TEST_MDM_ADMIN = new ComponentName(TEST_MDM_PACKAGE_NAME, 80 TEST_MDM_ADMIN_RECEIVER); 81 private static final PersistableBundle TEST_MDM_EXTRA_BUNDLE = createTestAdminExtras(); 82 private static final Account TEST_ACCOUNT = new Account("test@account.com", "account.type"); 83 private static final Intent ACTIVITY_INTENT = 84 new Intent("android.app.action.PROVISION_FINALIZATION_INSIDE_SUW"); 85 86 @Mock private Activity mActivity; 87 @Mock private Utils mUtils; 88 @Mock private SettingsFacade mSettingsFacade; 89 @Mock private UserProvisioningStateHelper mHelper; 90 @Mock private NotificationHelper mNotificationHelper; 91 @Mock private DeferredMetricsReader mDeferredMetricsReader; 92 @Mock private ProvisioningAnalyticsTracker mProvisioningAnalyticsTracker; 93 @Mock private UserManager mUserManager; 94 @Mock private DevicePolicyManager mDevicePolicyManager; 95 @Mock private SharedPreferences mSharedPreferences; 96 97 private PreFinalizationController mPreFinalizationController; 98 private FinalizationController mFinalizationController; 99 private final Context mTargetContext = InstrumentationRegistry.getTargetContext(); 100 @Mock private TransitionHelper mTransitionHelper; 101 102 @Override setUp()103 public void setUp() throws Exception { 104 // this is necessary for mockito to work 105 System.setProperty("dexmaker.dexcache", getContext().getCacheDir().toString()); 106 MockitoAnnotations.initMocks(this); 107 when(mActivity.getSystemService(Context.DEVICE_POLICY_SERVICE)) 108 .thenReturn(mDevicePolicyManager); 109 when(mActivity.getSystemServiceName(DevicePolicyManager.class)) 110 .thenReturn(Context.DEVICE_POLICY_SERVICE); 111 when(mUtils.canResolveIntentAsUser(any(Context.class), any(Intent.class), anyInt())) 112 .thenReturn(true); 113 when(mActivity.getFilesDir()).thenReturn(getContext().getFilesDir()); 114 when(mActivity.getIntent()).thenReturn(ACTIVITY_INTENT); 115 when(mActivity.bindService(any(Intent.class), any(ServiceConnection.class), anyInt())) 116 .thenReturn(false); 117 when(mActivity.getSystemServiceName(UserManager.class)) 118 .thenReturn(Context.USER_SERVICE); 119 when(mActivity.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager); 120 when(mActivity.getSharedPreferences(anyString(), anyInt())).thenReturn(mSharedPreferences); 121 when(mActivity.getResources()).thenReturn(mTargetContext.getResources()); 122 when(mUserManager.isUserUnlocked(anyInt())).thenReturn(true); 123 when(mUserManager.isUserUnlocked(any(UserHandle.class))).thenReturn(true); 124 125 final ProvisioningParamsUtils provisioningParamsUtils = 126 new ProvisioningParamsUtils( 127 ProvisioningParamsUtils.DEFAULT_PROVISIONING_PARAMS_FILE_PROVIDER); 128 mPreFinalizationController = new PreFinalizationController( 129 mActivity, mUtils, mSettingsFacade, mHelper, 130 provisioningParamsUtils, new SendDpcBroadcastServiceUtils()); 131 mFinalizationController = new FinalizationController( 132 mActivity, 133 new FinalizationInsideSuwControllerLogic( 134 mActivity, 135 mUtils, 136 new PolicyComplianceUtils(), 137 mProvisioningAnalyticsTracker, 138 mTransitionHelper), 139 mUtils, mSettingsFacade, mHelper, mNotificationHelper, mDeferredMetricsReader, 140 provisioningParamsUtils); 141 } 142 143 @Override tearDown()144 public void tearDown() throws Exception { 145 mFinalizationController.clearParamsFile(); 146 } 147 148 @SmallTest testFinalized_alreadyCalled()149 public void testFinalized_alreadyCalled() { 150 // GIVEN that deviceManagementEstablished has already been called 151 when(mHelper.isStateUnmanagedOrFinalized()).thenReturn(true); 152 final ProvisioningParams params = createProvisioningParams( 153 ACTION_PROVISION_MANAGED_PROFILE, false); 154 155 // WHEN calling provisioningFinalized and commitFinalizedState 156 mFinalizationController.provisioningFinalized(); 157 mFinalizationController.commitFinalizedState(); 158 159 // THEN nothing should happen 160 verify(mHelper, never()).markUserProvisioningStateInitiallyDone(params); 161 verify(mHelper, never()).markUserProvisioningStateFinalized(params); 162 verifyZeroInteractions(mDeferredMetricsReader); 163 } 164 165 @SmallTest testFinalized_noParamsStored()166 public void testFinalized_noParamsStored() { 167 // GIVEN that the user provisioning state is correct 168 when(mHelper.isStateUnmanagedOrFinalized()).thenReturn(false); 169 170 // WHEN calling provisioningFinalized and commitFinalizedState 171 mFinalizationController.provisioningFinalized(); 172 mFinalizationController.commitFinalizedState(); 173 174 // THEN nothing should happen 175 verify(mHelper, never()) 176 .markUserProvisioningStateInitiallyDone(any(ProvisioningParams.class)); 177 verify(mHelper, never()).markUserProvisioningStateFinalized(any(ProvisioningParams.class)); 178 verifyZeroInteractions(mDeferredMetricsReader); 179 } 180 181 @SmallTest testManagedProfileFinalizationDuringSuw()182 public void testManagedProfileFinalizationDuringSuw() { 183 // GIVEN that the DPC is not available on the primary profile 184 when(mUtils.canResolveIntentAsUser(eq(mActivity), any(Intent.class), 185 eq(UserHandle.USER_SYSTEM))).thenReturn(false); 186 // GIVEN that deviceManagementEstablished has never been called 187 when(mHelper.isStateUnmanagedOrFinalized()).thenReturn(true); 188 // GIVEN that we've provisioned a managed profile after SUW 189 final ProvisioningParams params = createProvisioningParams( 190 ACTION_PROVISION_MANAGED_PROFILE, true); 191 when(mSettingsFacade.isUserSetupCompleted(mActivity)).thenReturn(false); 192 when(mSettingsFacade.isDuringSetupWizard(mActivity)).thenReturn(true); 193 when(mUtils.getManagedProfile(mActivity)).thenReturn(MANAGED_PROFILE_USER_HANDLE); 194 195 // WHEN calling deviceManagementEstablished 196 mPreFinalizationController.deviceManagementEstablished(params); 197 198 // THEN the user provisioning state should be marked as initially done 199 verify(mHelper).markUserProvisioningStateInitiallyDone(params); 200 // THEN the provisioning params have been stored and will be read in provisioningFinalized 201 202 // GIVEN that the provisioning state is now incomplete 203 when(mHelper.isStateUnmanagedOrFinalized()).thenReturn(false); 204 205 // WHEN we save and restore controller state 206 saveAndRestoreControllerState(); 207 208 // THEN the user provisioning state is not yet finalized 209 verify(mHelper, never()).markUserProvisioningStateFinalized(params); 210 211 // THEN no intent should be sent to the dpc. 212 verify(mTransitionHelper, never()).startActivityForResultAsUserWithTransition( 213 eq(mActivity), any(Intent.class), anyInt(), eq(MANAGED_PROFILE_USER_HANDLE)); 214 215 // WHEN calling provisioningFinalized 216 mFinalizationController.provisioningFinalized(); 217 218 // THEN the user provisioning state is not yet finalized 219 verify(mHelper, never()).markUserProvisioningStateFinalized(params); 220 221 // THEN intent should be sent to the dpc. 222 verifyDpcLaunchedForUser(MANAGED_PROFILE_USER_HANDLE, 1); 223 224 // WHEN calling provisioningFinalized again 225 mFinalizationController.provisioningFinalized(); 226 227 // THEN the user provisioning state is not yet finalized 228 verify(mHelper, never()).markUserProvisioningStateFinalized(params); 229 230 // THEN intent should not be sent to the dpc again 231 verifyDpcLaunchedForUser(MANAGED_PROFILE_USER_HANDLE, 1); 232 233 // WHEN simulating a DPC cancel by calling activityDestroyed(true), and then 234 // provisioningFinalized again 235 mFinalizationController.activityDestroyed(true); 236 mFinalizationController.provisioningFinalized(); 237 238 // THEN the user provisioning state is not yet finalized 239 verify(mHelper, never()).markUserProvisioningStateFinalized(params); 240 241 // THEN intent should be sent to the dpc again 242 verifyDpcLaunchedForUser(MANAGED_PROFILE_USER_HANDLE, 2); 243 244 // WHEN we save and restore controller state, and then call provisioningFinalized again 245 saveAndRestoreControllerState(); 246 mFinalizationController.provisioningFinalized(); 247 248 // THEN the user provisioning state is not yet finalized 249 verify(mHelper, never()).markUserProvisioningStateFinalized(params); 250 251 // THEN intent is not sent to the dpc again 252 verifyDpcLaunchedForUser(MANAGED_PROFILE_USER_HANDLE, 2); 253 254 // WHEN the provisioning state changes are now committed 255 mFinalizationController.commitFinalizedState(); 256 257 // THEN deferred metrics have been written exactly once 258 verify(mDeferredMetricsReader).scheduleDumpMetrics(any(Context.class)); 259 verifyNoMoreInteractions(mDeferredMetricsReader); 260 261 // THEN the user provisioning state is finalized 262 verify(mHelper).markUserProvisioningStateFinalized(params); 263 264 // THEN the service which starts the DPC, has never been started. 265 verifySendDpcServiceNotStarted(); 266 } 267 268 @SmallTest testDeviceOwnerFinalizationDuringSuw()269 public void testDeviceOwnerFinalizationDuringSuw() { 270 // GIVEN that deviceManagementEstablished has never been called 271 when(mHelper.isStateUnmanagedOrFinalized()).thenReturn(true); 272 // GIVEN that we've provisioned a device owner during SUW 273 final ProvisioningParams params = createProvisioningParams( 274 ACTION_PROVISION_MANAGED_DEVICE, false); 275 when(mSettingsFacade.isUserSetupCompleted(mActivity)).thenReturn(false); 276 when(mSettingsFacade.isDuringSetupWizard(mActivity)).thenReturn(true); 277 278 // WHEN calling deviceManagementEstablished 279 mPreFinalizationController.deviceManagementEstablished(params); 280 281 // THEN the user provisioning state should be marked as initially done 282 verify(mHelper).markUserProvisioningStateInitiallyDone(params); 283 // THEN the provisioning params have been stored and will be read in provisioningFinalized 284 285 // GIVEN that the provisioning state is now incomplete 286 when(mHelper.isStateUnmanagedOrFinalized()).thenReturn(false); 287 288 // WHEN we save and restore controller state 289 saveAndRestoreControllerState(); 290 291 // THEN the user provisioning state is not yet finalized 292 verify(mHelper, never()).markUserProvisioningStateFinalized(params); 293 294 // THEN no intent should be sent to the dpc. 295 verify(mTransitionHelper, never()).startActivityForResultAsUserWithTransition( 296 eq(mActivity), any(Intent.class), anyInt(), 297 eq(UserHandle.of(UserHandle.myUserId()))); 298 299 // WHEN calling provisioningFinalized 300 mFinalizationController.provisioningFinalized(); 301 302 // THEN the user provisioning state is not yet finalized 303 verify(mHelper, never()).markUserProvisioningStateFinalized(params); 304 305 // THEN intent should be sent to the dpc. 306 verifyDpcLaunchedForUser(UserHandle.of(UserHandle.myUserId()), 1); 307 308 // WHEN calling provisioningFinalized again 309 mFinalizationController.provisioningFinalized(); 310 311 // THEN the user provisioning state is not yet finalized 312 verify(mHelper, never()).markUserProvisioningStateFinalized(params); 313 314 // THEN intent should not be sent to the dpc again 315 verifyDpcLaunchedForUser(UserHandle.of(UserHandle.myUserId()), 1); 316 317 // WHEN simulating a DPC cancel by calling activityDestroyed(true), and then 318 // provisioningFinalized again 319 mFinalizationController.activityDestroyed(true); 320 mFinalizationController.provisioningFinalized(); 321 322 // THEN the user provisioning state is not yet finalized 323 verify(mHelper, never()).markUserProvisioningStateFinalized(params); 324 325 // THEN intent should be sent to the dpc again 326 verifyDpcLaunchedForUser(UserHandle.of(UserHandle.myUserId()), 2); 327 328 // WHEN we save and restore controller state, and then call provisioningFinalized again 329 saveAndRestoreControllerState(); 330 mFinalizationController.provisioningFinalized(); 331 332 // THEN the user provisioning state is not yet finalized 333 verify(mHelper, never()).markUserProvisioningStateFinalized(params); 334 335 // THEN intent should not be sent to the dpc again 336 verifyDpcLaunchedForUser(UserHandle.of(UserHandle.myUserId()), 2); 337 338 // WHEN the provisioning state changes are now committed 339 mFinalizationController.commitFinalizedState(); 340 341 // THEN deferred metrics have been written exactly once 342 verify(mDeferredMetricsReader).scheduleDumpMetrics(any(Context.class)); 343 verifyNoMoreInteractions(mDeferredMetricsReader); 344 345 // THEN the user provisioning state is finalized 346 verify(mHelper).markUserProvisioningStateFinalized(params); 347 348 // THEN a privacy reminder is shown to the user exactly once 349 verify(mNotificationHelper).showPrivacyReminderNotification(eq(mActivity), anyInt()); 350 351 // THEN no broadcast was ever sent to the primary user 352 ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); 353 verify(mActivity, never()).sendBroadcast(intentCaptor.capture()); 354 } 355 356 @SmallTest testCorpOwnedManagedProfileDuringSuw()357 public void testCorpOwnedManagedProfileDuringSuw() throws PackageManager.NameNotFoundException { 358 // GIVEN that deviceManagementEstablished has never been called 359 when(mHelper.isStateUnmanagedOrFinalized()).thenReturn(true); 360 // GIVEN that we're provisioning a corp-owned managed profile DURING SUW 361 final ProvisioningParams params = 362 createProvisioningParamsBuilder(ACTION_PROVISION_MANAGED_PROFILE, true) 363 .setIsOrganizationOwnedProvisioning(true) 364 .setFlowType(ProvisioningParams.FLOW_TYPE_ADMIN_INTEGRATED) 365 .build(); 366 367 when(mSettingsFacade.isUserSetupCompleted(mActivity)).thenReturn(false); 368 when(mSettingsFacade.isDuringSetupWizard(mActivity)).thenReturn(true); 369 when(mUtils.getManagedProfile(mActivity)) 370 .thenReturn(MANAGED_PROFILE_USER_HANDLE); 371 372 final int managedProfileUserId = MANAGED_PROFILE_USER_HANDLE.getIdentifier(); 373 when(mDevicePolicyManager.getProfileOwnerAsUser(managedProfileUserId)) 374 .thenReturn(TEST_MDM_ADMIN); 375 376 // Actual Device IDs access is granted to the DPM of the managed profile, in the context 377 // of the managed profile. 378 final Context profileContext = mock(Context.class); 379 when(mActivity.createPackageContextAsUser(mActivity.getPackageName(), /*flags=*/ 0, 380 MANAGED_PROFILE_USER_HANDLE)).thenReturn(profileContext); 381 when(profileContext.getSystemServiceName(DevicePolicyManager.class)) 382 .thenReturn(Context.DEVICE_POLICY_SERVICE); 383 final DevicePolicyManager mockProfileDpm = mock(DevicePolicyManager.class); 384 when(profileContext.getSystemService(DevicePolicyManager.class)).thenReturn(mockProfileDpm); 385 386 // WHEN calling deviceManagementEstablished 387 mPreFinalizationController.deviceManagementEstablished(params); 388 389 // THEN the user provisioning state should be marked as initially done 390 verify(mHelper).markUserProvisioningStateInitiallyDone(params); 391 392 // GIVEN that the provisioning state is now incomplete 393 when(mHelper.isStateUnmanagedOrFinalized()).thenReturn(false); 394 395 // WHEN calling provisioningFinalized 396 mFinalizationController.provisioningFinalized(); 397 398 // THEN the user provisioning state is not yet finalized 399 verify(mHelper, never()).markUserProvisioningStateFinalized(params); 400 401 // THEN the DPC policy compliance screen should be shown on the work profile. 402 ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); 403 verify(mTransitionHelper).startActivityForResultAsUserWithTransition( 404 eq(mActivity), intentCaptor.capture(), anyInt(), eq(MANAGED_PROFILE_USER_HANDLE)); 405 assertThat(intentCaptor.getValue().getAction()) 406 .isEqualTo(DevicePolicyManager.ACTION_ADMIN_POLICY_COMPLIANCE); 407 408 // WHEN calling provisioningFinalized again 409 mFinalizationController.provisioningFinalized(); 410 411 // THEN the user provisioning state is not yet finalized 412 verify(mHelper, never()).markUserProvisioningStateFinalized(params); 413 414 // THEN the DPC policy compliance screen should be shown on the work profile. 415 intentCaptor = ArgumentCaptor.forClass(Intent.class); 416 verify(mTransitionHelper).startActivityForResultAsUserWithTransition( 417 eq(mActivity), intentCaptor.capture(), anyInt(), eq(MANAGED_PROFILE_USER_HANDLE)); 418 assertThat(intentCaptor.getValue().getAction()) 419 .isEqualTo(DevicePolicyManager.ACTION_ADMIN_POLICY_COMPLIANCE); 420 421 // WHEN the provisioning state changes are now committed 422 mFinalizationController.commitFinalizedState(); 423 424 // THEN deferred metrics are written exactly once 425 verify(mDeferredMetricsReader).scheduleDumpMetrics(any(Context.class)); 426 verifyNoMoreInteractions(mDeferredMetricsReader); 427 428 // THEN the user provisioning state is finalized 429 verify(mHelper).markUserProvisioningStateFinalized(params); 430 } 431 verifyDpcLaunchedForUser(UserHandle userHandle, int numTimes)432 private void verifyDpcLaunchedForUser(UserHandle userHandle, int numTimes) { 433 ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); 434 verify(mTransitionHelper, times(numTimes)).startActivityForResultAsUserWithTransition( 435 eq(mActivity), intentCaptor.capture(), anyInt(), eq(userHandle)); 436 final String intentAction = intentCaptor.getValue().getAction(); 437 // THEN the intent should be ACTION_PROVISIONING_SUCCESSFUL 438 assertEquals(ACTION_ADMIN_POLICY_COMPLIANCE, intentAction); 439 // THEN the intent should only be sent to the dpc 440 assertEquals(TEST_MDM_PACKAGE_NAME, intentCaptor.getValue().getPackage()); 441 // THEN the admin extras bundle should contain mdm extras 442 assertExtras(intentCaptor.getValue()); 443 // THEN a metric should be logged 444 verify(mProvisioningAnalyticsTracker, times(numTimes)).logDpcSetupStarted( 445 eq(mActivity), eq(intentAction)); 446 } 447 verifySendDpcServiceNotStarted()448 private void verifySendDpcServiceNotStarted() { 449 ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); 450 verify(mActivity, never()).startService(intentCaptor.capture()); 451 } 452 assertExtras(Intent intent)453 private void assertExtras(Intent intent) { 454 assertTrue(TestUtils.bundleEquals(TEST_MDM_EXTRA_BUNDLE, 455 (PersistableBundle) intent.getExtra(EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE))); 456 } 457 createProvisioningParams(String action, boolean migrateAccount)458 private ProvisioningParams createProvisioningParams(String action, boolean migrateAccount) { 459 return createProvisioningParamsBuilder(action, migrateAccount).build(); 460 } 461 createProvisioningParamsBuilder(String action, boolean migrateAccount)462 private ProvisioningParams.Builder createProvisioningParamsBuilder(String action, 463 boolean migrateAccount) { 464 ProvisioningParams.Builder builder = new ProvisioningParams.Builder() 465 .setDeviceAdminComponentName(TEST_MDM_ADMIN) 466 .setProvisioningAction(action) 467 .setAdminExtrasBundle(TEST_MDM_EXTRA_BUNDLE) 468 .setReturnBeforePolicyCompliance(true); 469 470 if (migrateAccount) { 471 builder.setAccountToMigrate(TEST_ACCOUNT); 472 builder.setKeepAccountMigrated(false); 473 } 474 475 return builder; 476 } 477 saveAndRestoreControllerState()478 private void saveAndRestoreControllerState() { 479 final Bundle savedInstanceState = new Bundle(); 480 mFinalizationController.saveInstanceState(savedInstanceState); 481 mFinalizationController.activityDestroyed(false); 482 mFinalizationController.restoreInstanceState(savedInstanceState); 483 } 484 } 485