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