diff options
7 files changed, 297 insertions, 75 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 9e944389f..00bdd4184 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -114,7 +114,8 @@ android:appCategory="social" android:supportsRtl="true" android:usesCleartextTraffic="false" - android:extractNativeLibs="false"> + android:extractNativeLibs="false" + android:requestLegacyExternalStorage="true"> </application> </manifest> diff --git a/java/com/android/dialer/binary/common/DialerApplication.java b/java/com/android/dialer/binary/common/DialerApplication.java index 31d4d828e..0f150253a 100644 --- a/java/com/android/dialer/binary/common/DialerApplication.java +++ b/java/com/android/dialer/binary/common/DialerApplication.java @@ -26,6 +26,7 @@ import com.android.dialer.calllog.CallLogComponent; import com.android.dialer.calllog.CallLogFramework; import com.android.dialer.calllog.config.CallLogConfig; import com.android.dialer.calllog.config.CallLogConfigComponent; +import com.android.dialer.callrecord.CallRecordingAutoMigrator; import com.android.dialer.common.LogUtil; import com.android.dialer.common.concurrent.DialerExecutorComponent; import com.android.dialer.inject.HasRootComponent; @@ -48,6 +49,10 @@ public abstract class DialerApplication extends Application implements HasRootCo new FilteredNumberAsyncQueryHandler(this), DialerExecutorComponent.get(this).dialerExecutorFactory()) .asyncAutoMigrate(); + new CallRecordingAutoMigrator( + this.getApplicationContext(), + DialerExecutorComponent.get(this).dialerExecutorFactory()) + .asyncAutoMigrate(); initializeAnnotatedCallLog(); PersistentLogger.initialize(this); diff --git a/java/com/android/dialer/calldetails/CallDetailsEntryViewHolder.java b/java/com/android/dialer/calldetails/CallDetailsEntryViewHolder.java index f1a9d7b42..a9be544a0 100644 --- a/java/com/android/dialer/calldetails/CallDetailsEntryViewHolder.java +++ b/java/com/android/dialer/calldetails/CallDetailsEntryViewHolder.java @@ -17,10 +17,12 @@ package com.android.dialer.calldetails; import android.content.ActivityNotFoundException; +import android.content.ContentUris; import android.content.Context; import android.content.Intent; import android.net.Uri; import android.provider.CallLog.Calls; +import android.provider.MediaStore; import android.support.annotation.ColorInt; import android.support.annotation.NonNull; import android.support.v4.content.ContextCompat; @@ -45,14 +47,13 @@ import com.android.dialer.callrecord.CallRecording; import com.android.dialer.callrecord.CallRecordingDataStore; import com.android.dialer.callrecord.impl.CallRecorderService; import com.android.dialer.common.LogUtil; -import com.android.dialer.constants.Constants; import com.android.dialer.enrichedcall.historyquery.proto.HistoryResult; import com.android.dialer.enrichedcall.historyquery.proto.HistoryResult.Type; import com.android.dialer.glidephotomanager.PhotoInfo; import com.android.dialer.oem.MotorolaUtils; import com.android.dialer.util.DialerUtils; import com.android.dialer.util.IntentUtil; -import java.io.File; + import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; @@ -269,9 +270,9 @@ public class CallDetailsEntryViewHolder extends ViewHolder { } private void playRecording(Context context, CallRecording recording) { - Uri uri = FileProvider.getUriForFile(context, - Constants.get().getFileProviderAuthority(), recording.getFile()); - String extension = MimeTypeMap.getFileExtensionFromUrl(uri.toString()); + Uri uri = ContentUris.withAppendedId( + MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, recording.mediaId); + String extension = MimeTypeMap.getFileExtensionFromUrl(recording.fileName); String mime = !TextUtils.isEmpty(extension) ? MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension) : "audio/*"; try { diff --git a/java/com/android/dialer/callrecord/CallRecording.java b/java/com/android/dialer/callrecord/CallRecording.java index 9fd77b46e..a887d1a56 100644 --- a/java/com/android/dialer/callrecord/CallRecording.java +++ b/java/com/android/dialer/callrecord/CallRecording.java @@ -16,9 +16,13 @@ package com.android.dialer.callrecord; +import android.content.ContentValues; import android.os.Environment; import android.os.Parcel; import android.os.Parcelable; +import android.provider.MediaStore; +import android.text.TextUtils; +import android.webkit.MimeTypeMap; import java.io.File; @@ -27,8 +31,7 @@ public final class CallRecording implements Parcelable { public long creationTime; public String fileName; public long startRecordingTime; - - private static final String PUBLIC_DIRECTORY_NAME = "CallRecordings"; + public long mediaId; public static final Parcelable.Creator<CallRecording> CREATOR = new Parcelable.Creator<CallRecording>() { @@ -44,11 +47,12 @@ public final class CallRecording implements Parcelable { }; public CallRecording(String phoneNumber, long creationTime, - String fileName, long startRecordingTime) { + String fileName, long startRecordingTime, long mediaId) { this.phoneNumber = phoneNumber; this.creationTime = creationTime; this.fileName = fileName; this.startRecordingTime = startRecordingTime; + this.mediaId = mediaId; } public CallRecording(Parcel in) { @@ -56,11 +60,29 @@ public final class CallRecording implements Parcelable { creationTime = in.readLong(); fileName = in.readString(); startRecordingTime = in.readLong(); + mediaId = in.readLong(); + } + + public static ContentValues generateMediaInsertValues(String fileName, long creationTime) { + final ContentValues cv = new ContentValues(5); + + cv.put(MediaStore.Audio.Media.RELATIVE_PATH, "Music/Call Recordings"); + cv.put(MediaStore.Audio.Media.DISPLAY_NAME, fileName); + cv.put(MediaStore.Audio.Media.DATE_TAKEN, creationTime); + cv.put(MediaStore.Audio.Media.IS_PENDING, 1); + + final String extension = MimeTypeMap.getFileExtensionFromUrl(fileName); + final String mime = !TextUtils.isEmpty(extension) + ? MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension) : "audio/*"; + cv.put(MediaStore.Audio.Media.MIME_TYPE, mime); + + return cv; } - public File getFile() { - File dir = Environment.getExternalStoragePublicDirectory(PUBLIC_DIRECTORY_NAME); - return new File(dir, fileName); + public static ContentValues generateCompletedValues() { + final ContentValues cv = new ContentValues(1); + cv.put(MediaStore.Audio.Media.IS_PENDING, 0); + return cv; } @Override @@ -69,6 +91,7 @@ public final class CallRecording implements Parcelable { out.writeLong(creationTime); out.writeString(fileName); out.writeLong(startRecordingTime); + out.writeLong(mediaId); } @Override diff --git a/java/com/android/dialer/callrecord/CallRecordingAutoMigrator.java b/java/com/android/dialer/callrecord/CallRecordingAutoMigrator.java new file mode 100644 index 000000000..bc29d22ce --- /dev/null +++ b/java/com/android/dialer/callrecord/CallRecordingAutoMigrator.java @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * Copyright (C) 2020 The LineageOS Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.dialer.callrecord; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.TargetApi; +import android.content.ContentResolver; +import android.content.Context; +import android.content.pm.PackageManager; +import android.net.Uri; +import android.os.Build; +import android.os.Environment; +import android.provider.MediaStore; +import android.text.TextUtils; +import android.util.SparseArray; + +import com.android.dialer.common.Assert; +import com.android.dialer.common.LogUtil; +import com.android.dialer.common.concurrent.DialerExecutor.Worker; +import com.android.dialer.common.concurrent.DialerExecutorFactory; +import com.android.voicemail.impl.mail.utils.LogUtils; + +import libcore.io.IoUtils; + +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.file.Files; + +public class CallRecordingAutoMigrator { + private static final String TAG = "CallRecordingAutoMigrator"; + + @NonNull + private final Context appContext; + @NonNull private final DialerExecutorFactory dialerExecutorFactory; + + public CallRecordingAutoMigrator( + @NonNull Context appContext, + @NonNull DialerExecutorFactory dialerExecutorFactory) { + this.appContext = Assert.isNotNull(appContext); + this.dialerExecutorFactory = Assert.isNotNull(dialerExecutorFactory); + } + + public void asyncAutoMigrate() { + dialerExecutorFactory + .createNonUiTaskBuilder(new ShouldAttemptAutoMigrate(appContext)) + .onSuccess(this::autoMigrate) + .build() + .executeParallel(null); + } + + @TargetApi(26) + private void autoMigrate(boolean shouldAttemptAutoMigrate) { + if (!shouldAttemptAutoMigrate) { + return; + } + + final CallRecordingDataStore store = new CallRecordingDataStore(); + store.open(appContext); + + final ContentResolver cr = appContext.getContentResolver(); + final SparseArray<CallRecording> oldRecordingData = store.getUnmigratedRecordingData(); + final File dir = Environment.getExternalStoragePublicDirectory("CallRecordings"); + for (File recording : dir.listFiles()) { + OutputStream os = null; + try { + // determine data store ID and call creation time of recording + int id = -1; + long creationTime = System.currentTimeMillis(); + for (int i = 0; i < oldRecordingData.size(); i++) { + if (TextUtils.equals(recording.getName(), oldRecordingData.get(i).fileName)) { + creationTime = oldRecordingData.get(i).creationTime; + id = oldRecordingData.keyAt(i); + break; + } + } + + // create media store entry for recording + Uri uri = cr.insert(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, + CallRecording.generateMediaInsertValues(recording.getName(), creationTime)); + os = cr.openOutputStream(uri); + + // copy file contents to media store stream + Files.copy(recording.toPath(), os); + + // insert media store id to store + if (id >= 0) { + store.updateMigratedRecording(id, Integer.parseInt(uri.getLastPathSegment())); + } + + // mark recording as complete + cr.update(uri, CallRecording.generateCompletedValues(), null, null); + + // delete file + LogUtils.i(TAG, "Successfully migrated recording " + recording + " (ID " + id + ")"); + recording.delete(); + } catch (IOException e) { + LogUtils.w(TAG, "Failed migrating call recording " + recording, e); + } finally { + if (os != null) { + IoUtils.closeQuietly(os); + } + } + } + + if (dir.listFiles().length == 0) { + dir.delete(); + } + + store.close(); + } + + private static class ShouldAttemptAutoMigrate implements Worker<Void, Boolean> { + private final Context appContext; + + ShouldAttemptAutoMigrate(Context appContext) { + this.appContext = appContext; + } + + @Nullable + @Override + public Boolean doInBackground(@Nullable Void input) { + if (Build.VERSION.SDK_INT < 26) { + return false; + } + if (appContext.checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) + != PackageManager.PERMISSION_GRANTED) { + LogUtil.i(TAG, "not attempting auto-migrate: no storage permission"); + return false; + } + + final File dir = Environment.getExternalStoragePublicDirectory("CallRecordings"); + if (!dir.exists()) { + LogUtil.i(TAG, "not attempting auto-migrate: no recordings present"); + return false; + } + + return true; + } + } +} diff --git a/java/com/android/dialer/callrecord/CallRecordingDataStore.java b/java/com/android/dialer/callrecord/CallRecordingDataStore.java index 59020ff3a..88b603b54 100644 --- a/java/com/android/dialer/callrecord/CallRecordingDataStore.java +++ b/java/com/android/dialer/callrecord/CallRecordingDataStore.java @@ -16,6 +16,7 @@ package com.android.dialer.callrecord; +import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; @@ -24,6 +25,7 @@ import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteStatement; import android.provider.BaseColumns; import android.util.Log; +import android.util.SparseArray; import java.util.ArrayList; import java.util.List; @@ -74,8 +76,9 @@ public class CallRecordingDataStore { CallRecordingsContract.CallRecording.COLUMN_NAME_PHONE_NUMBER + ", " + CallRecordingsContract.CallRecording.COLUMN_NAME_CALL_DATE + ", " + CallRecordingsContract.CallRecording.COLUMN_NAME_RECORDING_FILENAME + ", " + - CallRecordingsContract.CallRecording.COLUMN_NAME_CREATION_DATE + ") " + - " VALUES (?, ?, ?, ?)"; + CallRecordingsContract.CallRecording.COLUMN_NAME_CREATION_DATE + ", " + + CallRecordingsContract.CallRecording.COLUMN_NAME_MEDIA_ID + ") " + + " VALUES (?, ?, ?, ?, ?)"; try { SQLiteStatement stmt = mDatabase.compileStatement(insertSql); @@ -84,6 +87,7 @@ public class CallRecordingDataStore { stmt.bindLong(idx++, recording.creationTime); stmt.bindString(idx++, recording.fileName); stmt.bindLong(idx++, System.currentTimeMillis()); + stmt.bindLong(idx++, recording.mediaId); long id = stmt.executeInsert(); Log.i(TAG, "Saved recording " + recording + " with id " + id); } catch (SQLiteException e) { @@ -103,10 +107,12 @@ public class CallRecordingDataStore { final String query = "SELECT " + CallRecordingsContract.CallRecording.COLUMN_NAME_RECORDING_FILENAME + "," + - CallRecordingsContract.CallRecording.COLUMN_NAME_CREATION_DATE + + CallRecordingsContract.CallRecording.COLUMN_NAME_CREATION_DATE + "," + + CallRecordingsContract.CallRecording.COLUMN_NAME_MEDIA_ID + " FROM " + CallRecordingsContract.CallRecording.TABLE_NAME + " WHERE " + CallRecordingsContract.CallRecording.COLUMN_NAME_PHONE_NUMBER + " = ?" + " AND " + CallRecordingsContract.CallRecording.COLUMN_NAME_CALL_DATE + " = ?" + + " AND " + CallRecordingsContract.CallRecording.COLUMN_NAME_MEDIA_ID + " != 0" + " ORDER BY " + CallRecordingsContract.CallRecording.COLUMN_NAME_CREATION_DATE; String args[] = { @@ -118,11 +124,10 @@ public class CallRecordingDataStore { while (cursor.moveToNext()) { String fileName = cursor.getString(0); long creationDate = cursor.getLong(1); - CallRecording recording = - new CallRecording(phoneNumber, callCreationDate, fileName, creationDate); - if (recording.getFile().exists()) { - resultList.add(recording); - } + long mediaId = cursor.getLong(2); + // FIXME: need to check whether media entry still exists? + resultList.add( + new CallRecording(phoneNumber, callCreationDate, fileName, creationDate, mediaId)); } cursor.close(); } catch (SQLiteException e) { @@ -133,6 +138,42 @@ public class CallRecordingDataStore { return resultList; } + public SparseArray<CallRecording> getUnmigratedRecordingData() { + final String query = "SELECT " + + CallRecordingsContract.CallRecording._ID + "," + + CallRecordingsContract.CallRecording.COLUMN_NAME_PHONE_NUMBER + "," + + CallRecordingsContract.CallRecording.COLUMN_NAME_RECORDING_FILENAME + "," + + CallRecordingsContract.CallRecording.COLUMN_NAME_CREATION_DATE + + " FROM " + CallRecordingsContract.CallRecording.TABLE_NAME + + " WHERE " + CallRecordingsContract.CallRecording.COLUMN_NAME_MEDIA_ID + " == 0"; + final SparseArray<CallRecording> result = new SparseArray<>(); + + try { + Cursor cursor = mDatabase.rawQuery(query, null); + while (cursor.moveToNext()) { + int id = cursor.getInt(0); + String phoneNumber = cursor.getString(1); + String fileName = cursor.getString(2); + long creationDate = cursor.getLong(3); + CallRecording recording = new CallRecording( + phoneNumber, creationDate, fileName, creationDate, 0); + result.put(id, recording); + } + cursor.close(); + } catch (SQLiteException e) { + Log.w(TAG, "Failed to fetch recordings for migration", e); + } + + return result; + } + + public void updateMigratedRecording(int id, int mediaId) { + ContentValues cv = new ContentValues(1); + cv.put(CallRecordingsContract.CallRecording.COLUMN_NAME_MEDIA_ID, mediaId); + mDatabase.update(CallRecordingsContract.CallRecording.TABLE_NAME, cv, + CallRecordingsContract.CallRecording._ID + " = ?", new String[] { String.valueOf(id) }); + } + static class CallRecordingsContract { static interface CallRecording extends BaseColumns { static final String TABLE_NAME = "call_recordings"; @@ -140,11 +181,12 @@ public class CallRecordingDataStore { static final String COLUMN_NAME_CALL_DATE = "call_date"; static final String COLUMN_NAME_RECORDING_FILENAME = "recording_filename"; static final String COLUMN_NAME_CREATION_DATE = "creation_date"; + static final String COLUMN_NAME_MEDIA_ID = "media_id"; } } static class CallRecordingSQLiteOpenHelper extends SQLiteOpenHelper { - private static final int VERSION = 1; + private static final int VERSION = 2; private static final String DB_NAME = "callrecordings.db"; public CallRecordingSQLiteOpenHelper(Context context) { @@ -158,7 +200,8 @@ public class CallRecordingDataStore { CallRecordingsContract.CallRecording.COLUMN_NAME_PHONE_NUMBER + " TEXT," + CallRecordingsContract.CallRecording.COLUMN_NAME_CALL_DATE + " LONG," + CallRecordingsContract.CallRecording.COLUMN_NAME_RECORDING_FILENAME + " TEXT, " + - CallRecordingsContract.CallRecording.COLUMN_NAME_CREATION_DATE + " LONG" + + CallRecordingsContract.CallRecording.COLUMN_NAME_CREATION_DATE + " LONG," + + CallRecordingsContract.CallRecording.COLUMN_NAME_MEDIA_ID + " INTEGER DEFAULT 0" + ");" ); @@ -171,7 +214,11 @@ public class CallRecordingDataStore { @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { - // implement if we change the schema + if (oldVersion < 2) { + db.execSQL("ALTER TABLE " + CallRecordingsContract.CallRecording.TABLE_NAME + + " ADD COLUMN " + CallRecordingsContract.CallRecording.COLUMN_NAME_MEDIA_ID + + " INTEGER DEFAULT 0;"); + } } } } diff --git a/java/com/android/dialer/callrecord/impl/CallRecorderService.java b/java/com/android/dialer/callrecord/impl/CallRecorderService.java index 1d51d5a9e..298e8ade0 100644 --- a/java/com/android/dialer/callrecord/impl/CallRecorderService.java +++ b/java/com/android/dialer/callrecord/impl/CallRecorderService.java @@ -17,14 +17,17 @@ package com.android.dialer.callrecord.impl; import android.app.Service; +import android.content.ContentUris; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.media.MediaRecorder; -import android.media.MediaScannerConnection; +import android.net.Uri; import android.os.IBinder; +import android.os.ParcelFileDescriptor; import android.os.RemoteException; +import android.provider.MediaStore; import android.text.TextUtils; import android.provider.Settings; import android.util.Log; @@ -43,13 +46,7 @@ public class CallRecorderService extends Service { private static final String TAG = "CallRecorderService"; private static final boolean DBG = false; - private static enum RecorderState { - IDLE, - RECORDING - }; - private MediaRecorder mMediaRecorder = null; - private RecorderState mState = RecorderState.IDLE; private CallRecording mCurrentRecording = null; private SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyMMdd_HHmmssSSS"); @@ -57,24 +54,17 @@ public class CallRecorderService extends Service { private final ICallRecorderService.Stub mBinder = new ICallRecorderService.Stub() { @Override public CallRecording stopRecording() { - if (getState() == RecorderState.RECORDING) { - stopRecordingInternal(); - return mCurrentRecording; - } - return null; + return stopRecordingInternal(); } @Override public boolean startRecording(String phoneNumber, long creationTime) throws RemoteException { - String fileName = generateFilename(phoneNumber); - mCurrentRecording = new CallRecording(phoneNumber, creationTime, - fileName, System.currentTimeMillis()); - return startRecordingInternal(mCurrentRecording.getFile()); + return startRecordingInternal(phoneNumber, creationTime); } @Override public boolean isRecording() throws RemoteException { - return getState() == RecorderState.RECORDING; + return mMediaRecorder != null; } @Override @@ -115,7 +105,7 @@ public class CallRecorderService extends Service { return 0; } - private synchronized boolean startRecordingInternal(File file) { + private synchronized boolean startRecordingInternal(String phoneNumber, long creationTime) { if (mMediaRecorder != null) { if (DBG) { Log.d(TAG, "Start called with recording in progress, stopping current recording"); @@ -128,11 +118,6 @@ public class CallRecorderService extends Service { Log.w(TAG, "Record audio permission not granted, can't record call"); return false; } - if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) - != PackageManager.PERMISSION_GRANTED) { - Log.w(TAG, "External storage permission not granted, can't save recorded call"); - return false; - } if (DBG) Log.d(TAG, "Starting recording"); @@ -148,33 +133,37 @@ public class CallRecorderService extends Service { ? MediaRecorder.AudioEncoder.AMR_WB : MediaRecorder.AudioEncoder.AAC); } catch (IllegalStateException e) { Log.w(TAG, "Error initializing media recorder", e); + mMediaRecorder.reset(); + mMediaRecorder.release(); + mMediaRecorder = null; return false; } - file.getParentFile().mkdirs(); - String outputPath = file.getAbsolutePath(); - if (DBG) Log.d(TAG, "Writing output to file " + outputPath); + String fileName = generateFilename(phoneNumber); + Uri uri = getContentResolver().insert(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, + CallRecording.generateMediaInsertValues(fileName, creationTime)); try { - mMediaRecorder.setOutputFile(outputPath); + ParcelFileDescriptor pfd = getContentResolver().openFileDescriptor(uri, "w"); + if (pfd == null) { + throw new IOException("Opening file for URI " + uri + " failed"); + } + mMediaRecorder.setOutputFile(pfd.getFileDescriptor()); mMediaRecorder.prepare(); mMediaRecorder.start(); - mState = RecorderState.RECORDING; + + long mediaId = Long.parseLong(uri.getLastPathSegment()); + mCurrentRecording = new CallRecording(phoneNumber, creationTime, + fileName, System.currentTimeMillis(), mediaId); return true; - } catch (IOException e) { - Log.w(TAG, "Could not start recording for file " + outputPath, e); - Log.w(TAG, "Deleting failed recording " + outputPath); - file.delete(); - } catch (IllegalStateException e) { - Log.w(TAG, "Could not start recording for file " + outputPath, e); - Log.w(TAG, "Deleting failed recording " + outputPath); - file.delete(); + } catch (IOException | IllegalStateException e) { + Log.w(TAG, "Could not start recording", e); + getContentResolver().delete(uri, null, null); } catch (RuntimeException e) { + getContentResolver().delete(uri, null, null); // only catch exceptions thrown by the MediaRecorder JNI code if (e.getMessage().indexOf("start failed") >= 0) { - Log.w(TAG, "Could not start recording for file " + outputPath, e); - Log.w(TAG, "Deleting failed recording " + outputPath); - file.delete(); + Log.w(TAG, "Could not start recording", e); } else { throw e; } @@ -187,23 +176,26 @@ public class CallRecorderService extends Service { return false; } - private synchronized void stopRecordingInternal() { + private synchronized CallRecording stopRecordingInternal() { + CallRecording recording = mCurrentRecording; if (DBG) Log.d(TAG, "Stopping current recording"); if (mMediaRecorder != null) { try { - if (getState() == RecorderState.RECORDING) { - mMediaRecorder.stop(); - mMediaRecorder.reset(); - mMediaRecorder.release(); - } + mMediaRecorder.stop(); + mMediaRecorder.reset(); + mMediaRecorder.release(); } catch (IllegalStateException e) { Log.e(TAG, "Exception closing media recorder", e); } - MediaScannerConnection.scanFile(this, - new String[] { mCurrentRecording.fileName }, null, null); + + Uri uri = ContentUris.withAppendedId( + MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, mCurrentRecording.mediaId); + getContentResolver().update(uri, CallRecording.generateCompletedValues(), null, null); + mMediaRecorder = null; - mState = RecorderState.IDLE; + mCurrentRecording = null; } + return recording; } @Override @@ -212,10 +204,6 @@ public class CallRecorderService extends Service { if (DBG) Log.d(TAG, "Destroying CallRecorderService"); } - private synchronized RecorderState getState() { - return mState; - } - private String generateFilename(String number) { String timestamp = DATE_FORMAT.format(new Date()); |