• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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.networkconnection;
18 
19 import static java.util.Objects.requireNonNull;
20 
21 import android.content.Context;
22 import android.content.Intent;
23 import android.os.UserHandle;
24 
25 import androidx.annotation.NonNull;
26 import androidx.lifecycle.MutableLiveData;
27 import androidx.lifecycle.ViewModel;
28 import androidx.lifecycle.ViewModelProvider;
29 
30 import com.android.managedprovisioning.common.ErrorWrapper;
31 import com.android.managedprovisioning.common.IllegalProvisioningArgumentException;
32 import com.android.managedprovisioning.common.ProvisionLogger;
33 import com.android.managedprovisioning.common.SettingsFacade;
34 import com.android.managedprovisioning.common.SharedPreferences;
35 import com.android.managedprovisioning.common.Utils;
36 import com.android.managedprovisioning.model.ProvisioningParams;
37 import com.android.managedprovisioning.parser.MessageParser;
38 import com.android.managedprovisioning.provisioning.ProvisioningControllerCallback;
39 import com.android.managedprovisioning.provisioning.ProvisioningManagerHelper;
40 import com.android.managedprovisioning.task.TaskFactory;
41 
42 /**
43  * A {@link ViewModel} which manages the state for the network connection establishing screen.
44  */
45 public final class EstablishNetworkConnectionViewModel extends ViewModel implements
46         ProvisioningControllerCallback {
47 
48     public static final int STATE_IDLE = 1;
49     public static final int STATE_CONNECTING = 2;
50     public static final int STATE_SHOW_NETWORK_PICKER = 3;
51     public static final int STATE_ERROR = 4;
52     public static final int STATE_CONNECTED = 5;
53 
54     private final ProvisioningManagerHelper mProvisioningManagerHelper =
55             new ProvisioningManagerHelper();
56     private final MutableLiveData<Integer> mState = new MutableLiveData<>(STATE_IDLE);
57     private final Utils mUtils;
58     private final SettingsFacade mSettingsFacade;
59     private final SharedPreferences mSharedPreferences;
60     private ErrorWrapper mErrorWrapper;
61 
EstablishNetworkConnectionViewModel( Utils utils, SettingsFacade settingsFacade, SharedPreferences sharedPreferences)62     public EstablishNetworkConnectionViewModel(
63             Utils utils,
64             SettingsFacade settingsFacade,
65             SharedPreferences sharedPreferences) {
66         mUtils = requireNonNull(utils);
67         mSettingsFacade = requireNonNull(settingsFacade);
68         mSharedPreferences = requireNonNull(sharedPreferences);
69     }
70 
71     /**
72      * Parses and returns the provisioning extras contained in {@code intent}.
73      */
parseExtras(Context context, Intent intent)74     public ProvisioningParams parseExtras(Context context, Intent intent) {
75         requireNonNull(context);
76         requireNonNull(intent);
77         ProvisioningParams params = null;
78         try {
79             params = new MessageParser(context, mUtils).parse(intent);
80         } catch (IllegalProvisioningArgumentException e) {
81             ProvisionLogger.loge("Error parsing intent extras", e);
82         }
83         return params;
84     }
85 
86     /**
87      * Returns {@link MutableLiveData} describing the state.
88      */
observeState()89     public MutableLiveData<Integer> observeState() {
90         return mState;
91     }
92 
93     /**
94      * Connects to wifi or mobile data if needed.
95      */
connectToNetwork(Context context, ProvisioningParams params)96     public void connectToNetwork(Context context,
97             ProvisioningParams params) {
98         requireNonNull(context);
99         requireNonNull(params);
100         mSharedPreferences.setIsEstablishNetworkConnectionRun(true);
101         var networkCapabilities = mUtils.getActiveNetworkCapabilities(context);
102         if (networkCapabilities != null
103                 && mUtils.isNetworkConnectedToInternetViaEthernet(networkCapabilities)) {
104             updateState(STATE_CONNECTED);
105             return;
106         } else if (params.wifiInfo == null
107                 && !params.useMobileData) {
108             updateState(STATE_SHOW_NETWORK_PICKER);
109             return;
110         }
111         mProvisioningManagerHelper.startNewProvisioningLocked(
112                 EstablishNetworkConnectionController.createInstance(
113                         context,
114                         params,
115                         UserHandle.USER_SYSTEM,
116                         this,
117                         mUtils,
118                         mSettingsFacade,
119                         new TaskFactory()));
120         updateState(STATE_CONNECTING);
121     }
122 
123     @Override
cleanUpCompleted()124     public void cleanUpCompleted() {
125         mProvisioningManagerHelper.clearResourcesLocked();
126     }
127 
128     @Override
provisioningTasksCompleted()129     public void provisioningTasksCompleted() {
130         updateState(STATE_CONNECTED);
131     }
132 
133     @Override
error(int dialogTitleId, int errorMessageId, boolean factoryResetRequired)134     public void error(int dialogTitleId, int errorMessageId, boolean factoryResetRequired) {
135         mErrorWrapper = new ErrorWrapper(dialogTitleId, errorMessageId, factoryResetRequired);
136         updateState(STATE_ERROR);
137     }
138 
139     @Override
error(int dialogTitleId, String errorMessage, boolean factoryResetRequired)140     public void error(int dialogTitleId, String errorMessage, boolean factoryResetRequired) {
141         // We don't assign ErrorWrapper here since all errors would come as errorMessageId in the
142         // other override. This specific override is only meant for cases when the OEM returns
143         // a string error during the tasks. Today this only happens for the provisioning DPM APIs.
144         updateState(STATE_ERROR);
145     }
146 
updateState(int stateDownloading)147     private void updateState(int stateDownloading) {
148         if (stateDownloading != STATE_ERROR) {
149             mErrorWrapper = null;
150         }
151         mState.postValue(stateDownloading);
152     }
153 
154     /**
155      * Returns an {@link ErrorWrapper} which describes the last error that happened. This will
156      * only be non-{@code null} if {@link #observeState()} returns {@link #STATE_ERROR}.
157      */
getError()158     public ErrorWrapper getError() {
159         return mErrorWrapper;
160     }
161 
162     @Override
preFinalizationCompleted()163     public void preFinalizationCompleted() {
164     }
165 
166     static class EstablishNetworkConnectionViewModelFactory implements ViewModelProvider.Factory {
167         private final Utils mUtils;
168         private final SettingsFacade mSettingsFacade;
169         private final SharedPreferences mSharedPreferences;
170 
EstablishNetworkConnectionViewModelFactory( Utils utils, SettingsFacade settingsFacade, SharedPreferences sharedPreferences)171         EstablishNetworkConnectionViewModelFactory(
172                 Utils utils,
173                 SettingsFacade settingsFacade,
174                 SharedPreferences sharedPreferences) {
175             mUtils = requireNonNull(utils);
176             mSettingsFacade = requireNonNull(settingsFacade);
177             mSharedPreferences = requireNonNull(sharedPreferences);
178         }
179 
180         @NonNull
181         @Override
182         @SuppressWarnings("unchecked")
create(@onNull Class<T> modelClass)183         public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
184             if (!EstablishNetworkConnectionViewModel.class.isAssignableFrom(modelClass)) {
185                 throw new IllegalArgumentException("Invalid class for creating a "
186                         + "EstablishNetworkConnectionViewModel: " + modelClass);
187             }
188             return (T) new EstablishNetworkConnectionViewModel(
189                     mUtils, mSettingsFacade, mSharedPreferences);
190         }
191     }
192 }
193