1 /*
2  * Copyright (C) 2018 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 package android.car.cluster;
17 import android.os.Handler;
18 import android.util.Log;
19 
20 import java.io.IOException;
21 import java.io.RandomAccessFile;
22 import java.nio.ByteBuffer;
23 import java.nio.ByteOrder;
24 
25 /**
26  * Thread that can send data to the emulator using a qemud service.
27  */
28 public class PipeThread extends SenderThread {
29     private static final String TAG = "Cluster." + PipeThread.class.getSimpleName();
30 
31     private RandomAccessFile mPipe;
32 
33     /**
34      * Creates instance of pipe thread that can write to given pipe file.
35      *
36      * @param handler {@link Handler} used to message broadcaster.
37      * @param pipe {@link RandomAccessFile} file already connected to pipe.
38      */
PipeThread(Handler handler, RandomAccessFile pipe)39     PipeThread(Handler handler, RandomAccessFile pipe) {
40         super(handler);
41         mPipe = pipe;
42     }
43 
run()44     public void run() {
45         try {
46             int signal = mPipe.read();
47             while (signal != NetworkedVirtualDisplay.PIPE_STOP) {
48                 Log.i(TAG, "Received non-stop signal: " + signal);
49                 signal = mPipe.read();
50             }
51             restart();
52         } catch (IOException e) {
53             Log.e(TAG, "Failed to read from pipe");
54             restart();
55         }
56     }
57 
58     @Override
send(byte[] buf, int len)59     public void send(byte[] buf, int len) {
60         try {
61             // First sends the size prior to sending the data, since receiving side only sees
62             // the size of the buffer, which could be significant larger than the actual data.
63             mPipe.write(ByteBuffer.allocate(4)
64                           .order(ByteOrder.LITTLE_ENDIAN).putInt(len).array());
65             mPipe.write(buf);
66         } catch (IOException e) {
67             Log.e(TAG, "Write to pipe failed");
68             restart();
69         }
70     }
71 
72     @Override
close()73     public void close() {
74         try {
75             mPipe.close();
76         } catch (IOException e) {
77             Log.e(TAG, "Failed to close pipe", e);
78         }
79     }
80 }
81 
82