17d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon/* 27d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Copyright (C) 2010 The Android Open Source Project 37d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 47d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Licensed under the Apache License, Version 2.0 (the "License"); 57d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * you may not use this file except in compliance with the License. 67d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * You may obtain a copy of the License at 77d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 87d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * http://www.apache.org/licenses/LICENSE-2.0 97d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Unless required by applicable law or agreed to in writing, software 117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * distributed under the License is distributed on an "AS IS" BASIS, 127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * See the License for the specific language governing permissions and 147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * limitations under the License. 157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonpackage com.android.phone.sip; 187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.os.AtomicFile; 207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.content.Context; 227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.net.sip.SipProfile; 237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.util.Log; 247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport java.io.File; 267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport java.io.FileInputStream; 277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport java.io.FileOutputStream; 287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport java.io.IOException; 297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport java.io.ObjectInputStream; 307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport java.io.ObjectOutputStream; 317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport java.util.ArrayList; 327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport java.util.Collections; 337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport java.util.List; 347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon/** 367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Utility class that helps perform operations on the SipProfile database. 377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonpublic class SipProfileDb { 397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final String TAG = SipProfileDb.class.getSimpleName(); 407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final String PROFILES_DIR = "/profiles/"; 427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final String PROFILE_OBJ_FILE = ".pobj"; 437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private String mProfilesDirectory; 457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private SipSharedPreferences mSipSharedPreferences; 467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private int mProfilesCount = -1; 477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public SipProfileDb(Context context) { 497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mProfilesDirectory = context.getFilesDir().getAbsolutePath() 507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon + PROFILES_DIR; 517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mSipSharedPreferences = new SipSharedPreferences(context); 527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void deleteProfile(SipProfile p) { 557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized(SipProfileDb.class) { 567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon deleteProfile(new File(mProfilesDirectory + p.getProfileName())); 577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mProfilesCount < 0) retrieveSipProfileListInternal(); 587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mSipSharedPreferences.setProfilesCount(--mProfilesCount); 597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void deleteProfile(File file) { 637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (file.isDirectory()) { 647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon for (File child : file.listFiles()) deleteProfile(child); 657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon file.delete(); 677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void saveProfile(SipProfile p) throws IOException { 707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized(SipProfileDb.class) { 717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mProfilesCount < 0) retrieveSipProfileListInternal(); 727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon File f = new File(mProfilesDirectory + p.getProfileName()); 737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (!f.exists()) f.mkdirs(); 747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon AtomicFile atomicFile = 757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon new AtomicFile(new File(f, PROFILE_OBJ_FILE)); 767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon FileOutputStream fos = null; 777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ObjectOutputStream oos = null; 787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon fos = atomicFile.startWrite(); 807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon oos = new ObjectOutputStream(fos); 817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon oos.writeObject(p); 827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon oos.flush(); 837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mSipSharedPreferences.setProfilesCount(++mProfilesCount); 847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon atomicFile.finishWrite(fos); 857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (IOException e) { 867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon atomicFile.failWrite(fos); 877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon throw e; 887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } finally { 897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (oos != null) oos.close(); 907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getProfilesCount() { 957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return (mProfilesCount < 0) ? 967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mSipSharedPreferences.getProfilesCount() : mProfilesCount; 977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public List<SipProfile> retrieveSipProfileList() { 1007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized(SipProfileDb.class) { 1017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return retrieveSipProfileListInternal(); 1027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private List<SipProfile> retrieveSipProfileListInternal() { 1067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon List<SipProfile> sipProfileList = Collections.synchronizedList( 1077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon new ArrayList<SipProfile>()); 1087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon File root = new File(mProfilesDirectory); 1107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon String[] dirs = root.list(); 1117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (dirs == null) return sipProfileList; 1127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon for (String dir : dirs) { 1137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon File f = new File(new File(root, dir), PROFILE_OBJ_FILE); 1147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (!f.exists()) continue; 1157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 1167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon SipProfile p = deserialize(f); 1177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (p == null) continue; 1187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (!dir.equals(p.getProfileName())) continue; 1197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon sipProfileList.add(p); 1217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (IOException e) { 1227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.e(TAG, "retrieveProfileListFromStorage()", e); 1237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mProfilesCount = sipProfileList.size(); 1267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mSipSharedPreferences.setProfilesCount(mProfilesCount); 1277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return sipProfileList; 1287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private SipProfile deserialize(File profileObjectFile) throws IOException { 1317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon AtomicFile atomicFile = new AtomicFile(profileObjectFile); 1327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ObjectInputStream ois = null; 1337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 1347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ois = new ObjectInputStream(atomicFile.openRead()); 1357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon SipProfile p = (SipProfile) ois.readObject(); 1367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return p; 1377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (ClassNotFoundException e) { 1387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.w(TAG, "deserialize a profile: " + e); 1397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } finally { 1407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (ois!= null) ois.close(); 1417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return null; 1437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon} 145