blob: 8f09eb7c19ab66f27658fefd3dc60942739ba014 [file] [log] [blame]
Jaewan Kim63461552014-03-10 17:10:51 +09001/*
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.server.net;
18
19import android.os.Handler;
20import android.os.HandlerThread;
21import android.text.TextUtils;
22import android.util.Log;
23
24import java.io.BufferedOutputStream;
25import java.io.DataOutputStream;
26import java.io.FileOutputStream;
27import java.io.IOException;
28
29public class DelayedDiskWrite {
30 private HandlerThread mDiskWriteHandlerThread;
31 private Handler mDiskWriteHandler;
32 /* Tracks multiple writes on the same thread */
33 private int mWriteSequence = 0;
34 private final String TAG = "DelayedDiskWrite";
35
36 public interface Writer {
37 public void onWriteCalled(DataOutputStream out) throws IOException;
38 }
39
40 public void write(final String filePath, final Writer w) {
Jan Nordqviste5779d72015-04-23 15:42:55 -070041 write(filePath, w, true);
42 }
43
44 public void write(final String filePath, final Writer w, final boolean open) {
Jaewan Kim63461552014-03-10 17:10:51 +090045 if (TextUtils.isEmpty(filePath)) {
46 throw new IllegalArgumentException("empty file path");
47 }
48
49 /* Do a delayed write to disk on a separate handler thread */
50 synchronized (this) {
51 if (++mWriteSequence == 1) {
52 mDiskWriteHandlerThread = new HandlerThread("DelayedDiskWriteThread");
53 mDiskWriteHandlerThread.start();
54 mDiskWriteHandler = new Handler(mDiskWriteHandlerThread.getLooper());
55 }
56 }
57
58 mDiskWriteHandler.post(new Runnable() {
59 @Override
60 public void run() {
Jan Nordqviste5779d72015-04-23 15:42:55 -070061 doWrite(filePath, w, open);
Jaewan Kim63461552014-03-10 17:10:51 +090062 }
63 });
64 }
65
Jan Nordqviste5779d72015-04-23 15:42:55 -070066 private void doWrite(String filePath, Writer w, boolean open) {
Jaewan Kim63461552014-03-10 17:10:51 +090067 DataOutputStream out = null;
68 try {
Jan Nordqviste5779d72015-04-23 15:42:55 -070069 if (open) {
70 out = new DataOutputStream(new BufferedOutputStream(
Jaewan Kim63461552014-03-10 17:10:51 +090071 new FileOutputStream(filePath)));
Jan Nordqviste5779d72015-04-23 15:42:55 -070072 }
Jaewan Kim63461552014-03-10 17:10:51 +090073 w.onWriteCalled(out);
74 } catch (IOException e) {
75 loge("Error writing data file " + filePath);
76 } finally {
77 if (out != null) {
78 try {
79 out.close();
80 } catch (Exception e) {}
81 }
82
83 // Quit if no more writes sent
84 synchronized (this) {
85 if (--mWriteSequence == 0) {
86 mDiskWriteHandler.getLooper().quit();
87 mDiskWriteHandler = null;
88 mDiskWriteHandlerThread = null;
89 }
90 }
91 }
92 }
93
94 private void loge(String s) {
95 Log.e(TAG, s);
96 }
97}
98