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 android.app.Activity;
20 import android.os.Bundle;
21 import android.os.StrictMode;
22 
23 /**
24  * Instances of this base class manage interactions with a Device Policy Controller app after it has
25  * been set up as either a Device Owner or a Profile Owner.
26  *
27  * Once we are sure that the DPC app has had an opportunity to run its own setup activities, we
28  * record in the system that provisioning has been finalized.
29  *
30  * Different instances of this class will be tailored to run at different points in the Setup
31  * Wizard user flows.
32  */
33 public abstract class FinalizationActivityBase extends Activity {
34 
35     private static final String CONTROLLER_STATE_KEY = "controller_state";
36 
37     private FinalizationController mFinalizationController;
38 
39     @Override
onCreate(Bundle savedInstanceState)40     public final void onCreate(Bundle savedInstanceState) {
41         // TODO(b/123987694): Investigate use of buffered i/o for provisioning params file
42         StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
43                 .permitUnbufferedIo()
44                 .build());
45 
46         super.onCreate(savedInstanceState);
47 
48         mFinalizationController = createFinalizationController();
49 
50         if (savedInstanceState != null) {
51             final Bundle controllerState = savedInstanceState.getBundle(CONTROLLER_STATE_KEY);
52             if (controllerState != null) {
53                 mFinalizationController.restoreInstanceState(controllerState);
54             }
55 
56             // If savedInstanceState is not null, we already executed the logic below, so don't do
57             // it again now.  We likely just need to wait for a child activity to complete, so we
58             // can execute an onActivityResult() callback before finishing this activity.
59             return;
60         }
61 
62         mFinalizationController.provisioningFinalized();
63         final int result = mFinalizationController.getProvisioningFinalizedResult();
64         if (FinalizationController.PROVISIONING_FINALIZED_RESULT_CHILD_ACTIVITY_LAUNCHED ==
65                 result) {
66             onFinalizationCompletedWithChildActivityLaunched();
67         } else {
68             if (FinalizationController.PROVISIONING_FINALIZED_RESULT_SKIPPED != result) {
69                 mFinalizationController.commitFinalizedState();
70             }
71             setResult(RESULT_OK);
72             finish();
73         }
74     }
75 
76     @Override
onSaveInstanceState(Bundle outState)77     protected final void onSaveInstanceState(Bundle outState) {
78         super.onSaveInstanceState(outState);
79 
80         final Bundle controllerState = new Bundle();
81         outState.putBundle(CONTROLLER_STATE_KEY, controllerState);
82         mFinalizationController.saveInstanceState(controllerState);
83     }
84 
85     @Override
onDestroy()86     public final void onDestroy() {
87         mFinalizationController.activityDestroyed(isFinishing());
88         super.onDestroy();
89     }
90 
91     /**
92      * Return the finalization controller instance that was constructed in {@link #onCreate}.
93      */
getFinalizationController()94     protected FinalizationController getFinalizationController() {
95         return mFinalizationController;
96     }
97 
98     /**
99      * Construct the correct subtype of FinalizationController.
100      */
createFinalizationController()101     protected abstract FinalizationController createFinalizationController();
102 
103     /**
104      * Hook for code that should run when the controller has launched a child activity.
105      */
onFinalizationCompletedWithChildActivityLaunched()106     protected abstract void onFinalizationCompletedWithChildActivityLaunched();
107 }
108