1/* 2 * Copyright (C) 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 17package com.android.omadm.service; 18 19import android.util.Log; 20 21import java.io.File; 22import java.io.FilenameFilter; 23 24class DMSession { 25 private static final String TAG = "DMSession"; 26 private static final boolean DBG = DMClientService.DBG; 27 28 private final String mLogPath; 29 30 private int mResultCode; 31 32 private DMHttpConnector mHttpConnector; 33 34 private final DMAlert mDMAlert; 35 36 private final DMClientService mDMClientService; 37 38 private String mLogName; 39 40 private String mServerID; 41 42 public String getLogFileName() { 43 return mLogName; 44 } 45 46 DMSession(DMClientService context) { 47 mLogName = null; 48 mDMClientService = context; 49 mDMAlert = new DMAlert(context); 50 mLogPath = context.getFilesDir().getPath() + "/dm/log/"; 51 if (DBG) logd("XXX DMSession mLogPath dir = " + mLogPath); 52 } 53 54 public int startClientSession(String serverID) { 55 prepareLogFile(); 56 57 try { 58 mServerID = serverID; 59 mHttpConnector = new DMHttpConnector(this); 60 61 if (DBG) logd("Start client session with server: " + mServerID); 62 mResultCode = NativeDM.startClientSession(mServerID, this); 63 64 logd("startDmSession resultCode: " + mResultCode); 65 } catch (RuntimeException e) { 66 loge("Exception caught starting DM session", e); 67 } 68 69 mHttpConnector.closeSession(); 70 mHttpConnector = null; 71 mLogName = null; 72 73 return mResultCode; 74 } 75 76 public int startFotaClientSession(String serverID, String alertStr) { 77 prepareLogFile(); 78 79 try { 80 mServerID = serverID; 81 mHttpConnector = new DMHttpConnector(this); 82 83 if (DBG) logd("Start DM session with server: " + mServerID 84 + " alert string: " + alertStr); 85 mResultCode = NativeDM.startFotaClientSession(serverID, alertStr, this); 86 87 logd("startDmSession resultCode: " + mResultCode); 88 } catch (Exception e) { 89 loge("Exception caught starting DM session", e); 90 } 91 92 mHttpConnector.closeSession(); 93 mHttpConnector = null; 94 mLogName = null; 95 96 return mResultCode; 97 } 98 99 public int startLawmoNotifySession(FotaNotifyContext LawmoContext) { 100 prepareLogFile(); 101 102 try { 103 mServerID = mDMClientService.getConfigDB().getFotaServerID(); 104 mHttpConnector = new DMHttpConnector(this); 105 106 if (DBG) logd("Start LAWMONotify session with server: " + mServerID 107 + " PkgURI: " + LawmoContext.mPkgURI 108 + " AlertType: " + LawmoContext.mAlertType 109 + " Result: " + LawmoContext.mResult); 110 mResultCode = NativeDM.startFotaNotifySession( 111 LawmoContext.mResult, 112 LawmoContext.mPkgURI, 113 LawmoContext.mAlertType, 114 mServerID, 115 LawmoContext.mCorrelator, 116 this); 117 logd("LAWMONotifySession resultCode: " + mResultCode); 118 } catch (Exception e) { 119 loge("Exception caught starting DM session", e); 120 } 121 122 mHttpConnector.closeSession(); 123 mHttpConnector = null; 124 mLogName = null; 125 126 return mResultCode; 127 } 128 129 public int startPkg0AlertSession(byte[] data) { 130 DMPkg0Notification notification = new DMPkg0Notification(); 131 int ret = NativeDM.parsePkg0(data, notification); 132 if (ret != DMResult.SYNCML_DM_SUCCESS) { 133 if (ret != DMResult.SYNCML_DM_SESSION_AUTH_FAIL) { 134 logd("parsePkg0 return:" + ret); 135 return ret; 136 } 137 if (mDMClientService.getConfigDB().isDmNonceResyncEnabled()) { 138 logd("Nonce resync enabled, ignore as per OMA DM spec."); 139 return ret; 140 } 141 } 142 143 if (DBG) logd("NativeDM.parsePkg0 result: uiMode: " + notification.getUIMode() 144 + " initiator: " + notification.getInitiator() 145 + " sessionId: " + notification.getSessionID() 146 + " serverId: " + notification.getServerID()); 147 148 if (notification.getServerID() == null) { 149 return DMResult.SYNCML_DM_SESSION_PARAM_ERR; 150 } 151 152 if (notification.getUIMode() == 3 || notification.getUIMode() == 0) { 153 mDMAlert.setUIMode(mDMClientService.getConfigDB().isDmAlertEnabled()); 154 } else { 155 mDMAlert.setUIMode(false); 156 } 157 prepareLogFile(); 158 159 mServerID = notification.getServerID(); 160 mHttpConnector = new DMHttpConnector(this); 161 162 try { 163 if (notification.getInitiator() == 1) { 164 logd("Start server initiated session"); 165 mResultCode = NativeDM.startFotaServerSession(notification.getServerID(), 166 notification.getSessionID(), 167 this); 168 } else { 169 logd("Start client initiated session"); 170 String alertStr = "org.openmobilealliance.dm.firmwareupdate.userrequest"; 171 mResultCode = NativeDM.startFotaClientSession(notification.getServerID(), alertStr, 172 this); 173 } 174 175 logd("startDmSession resultCode: " + mResultCode); 176 177 if (mResultCode == DMResult.SYNCML_DM_SUCCESS) { 178 mDMClientService.getConfigDB().setFotaServerID(notification.getServerID()); 179 } 180 } catch (Exception e) { 181 loge("Exception caught starting DM session", e); 182 } 183 184 mHttpConnector.closeSession(); 185 mHttpConnector = null; 186 mLogName = null; 187 188 return mResultCode; 189 } 190 191 public int fotaNotifyDMServer(FotaNotifyContext fotaContext) { 192 prepareLogFile(); 193 194 try { 195 mServerID = fotaContext.mServerID; 196 mHttpConnector = new DMHttpConnector(this); 197 198 mResultCode = NativeDM.startFotaNotifySession( 199 fotaContext.mResult, 200 fotaContext.mPkgURI, 201 fotaContext.mAlertType, 202 fotaContext.mServerID, 203 fotaContext.mCorrelator, 204 this); 205 if (DBG) logd("fotaNotifyDMServer resultCode: " + mResultCode); 206 } catch (Exception e) { 207 loge("Exception caught starting DM session", e); 208 } 209 210 mHttpConnector.closeSession(); 211 mHttpConnector = null; 212 mLogName = null; 213 214 return mResultCode; 215 } 216 217 public int cancelSession() { 218 NativeDM.cancelSession(); // Just set cancel flag. 219 220 mHttpConnector.closeSession(); 221 mHttpConnector = null; 222 223 mDMAlert.cancelSession(); 224 return 0; 225 } 226 227 private void prepareLogFile() { 228 File dirs = new File(mLogPath); 229 FilenameFilter filter = new SyncMLFilenameFilter(); 230 231 int maxNum = 0; 232 String[] files = dirs.list(filter); 233 234 if(files != null) { 235 for (String f : files) { 236 String digitalStr = f.substring(7, 8); 237 try { 238 int number = Integer.parseInt(digitalStr); 239 if (number > maxNum) { 240 maxNum = number; 241 } 242 243 } catch (NumberFormatException e) { 244 loge("NumberFormatException in prepareLogFile()", e); 245 } 246 } 247 maxNum++; 248 } 249 250 if (files == null || maxNum >= 10) { 251 // FIXME: check return value 252 dirs.delete(); 253 // FIXME: check return value 254 dirs.mkdirs(); 255 maxNum = 1; 256 } 257 258 String num = Integer.toString(maxNum); 259 String logName = "SyncML_" + num + ".txt"; 260 mLogName = mLogPath + logName; 261 if (DBG) logd("Log File: " + mLogName); 262 } 263 264 public DMClientService getServiceContext() { 265 return mDMClientService; 266 } 267 268 /** 269 * Get the {@link DMHttpConnector} object for this session. Called from JNI code. 270 * 271 * @return the DMHttpConnector object for this session 272 */ 273 public DMHttpConnector getNetConnector() { 274 return mHttpConnector; 275 } 276 277 /** 278 * Get the {@link DMAlert} object for this session. Called from JNI code. 279 * 280 * @return the DMAlert object for this session 281 */ 282 public DMAlert getDMAlert() { 283 return mDMAlert; 284 } 285 286 // FIXME: remove if unused?! 287 public String getServerID() { 288 return mServerID; 289 } 290 291 private static class SyncMLFilenameFilter implements FilenameFilter { 292 293 SyncMLFilenameFilter() { 294 } 295 296 @Override 297 public boolean accept(File dir, String name) { 298 return name.endsWith(".txt") && name.startsWith("SyncML_"); 299 } 300 } 301 302 private static void logd(String msg) { 303 Log.d(TAG, msg); 304 } 305 306 private static void loge(String msg, Throwable tr) { 307 Log.e(TAG, msg, tr); 308 } 309} 310