1 /*
2  * Copyright (C) 2016 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 
17 package android.os;
18 
19 import android.util.Log;
20 
21 import com.android.internal.os.IShellCallback;
22 
23 /**
24  * Special-purpose API for use with {@link IBinder#shellCommand IBinder.shellCommand} for
25  * performing operations back on the invoking shell.
26  * @hide
27  */
28 public class ShellCallback implements Parcelable {
29     final static String TAG = "ShellCallback";
30 
31     final static boolean DEBUG = false;
32 
33     final boolean mLocal;
34 
35     IShellCallback mShellCallback;
36 
37     class MyShellCallback extends IShellCallback.Stub {
openOutputFile(String path, String seLinuxContext)38         public ParcelFileDescriptor openOutputFile(String path, String seLinuxContext) {
39             return onOpenOutputFile(path, seLinuxContext);
40         }
41     }
42 
43     /**
44      * Create a new ShellCallback to receive requests.
45      */
ShellCallback()46     public ShellCallback() {
47         mLocal = true;
48     }
49 
50     /**
51      * Ask the shell to open a file for writing.  This will truncate the file if it
52      * already exists.  It will create the file if it doesn't exist.
53      * @param path Path of the file to be opened/created.
54      * @param seLinuxContext Optional SELinux context that must be allowed to have
55      * access to the file; if null, nothing is required.
56      */
openOutputFile(String path, String seLinuxContext)57     public ParcelFileDescriptor openOutputFile(String path, String seLinuxContext) {
58         if (DEBUG) Log.d(TAG, "openOutputFile " + this + ": mLocal=" + mLocal
59                 + " mShellCallback=" + mShellCallback);
60 
61         if (mLocal) {
62             return onOpenOutputFile(path, seLinuxContext);
63         }
64 
65         if (mShellCallback != null) {
66             try {
67                 return mShellCallback.openOutputFile(path, seLinuxContext);
68             } catch (RemoteException e) {
69                 Log.w(TAG, "Failure opening " + path, e);
70             }
71         }
72         return null;
73     }
74 
onOpenOutputFile(String path, String seLinuxContext)75     public ParcelFileDescriptor onOpenOutputFile(String path, String seLinuxContext) {
76         return null;
77     }
78 
writeToParcel(ShellCallback callback, Parcel out)79     public static void writeToParcel(ShellCallback callback, Parcel out) {
80         if (callback == null) {
81             out.writeStrongBinder(null);
82         } else {
83             callback.writeToParcel(out, 0);
84         }
85     }
86 
describeContents()87     public int describeContents() {
88         return 0;
89     }
90 
writeToParcel(Parcel out, int flags)91     public void writeToParcel(Parcel out, int flags) {
92         synchronized (this) {
93             if (mShellCallback == null) {
94                 mShellCallback = new MyShellCallback();
95             }
96             out.writeStrongBinder(mShellCallback.asBinder());
97         }
98     }
99 
ShellCallback(Parcel in)100     ShellCallback(Parcel in) {
101         mLocal = false;
102         mShellCallback = IShellCallback.Stub.asInterface(in.readStrongBinder());
103     }
104 
105     public static final Parcelable.Creator<ShellCallback> CREATOR
106             = new Parcelable.Creator<ShellCallback>() {
107         public ShellCallback createFromParcel(Parcel in) {
108             return new ShellCallback(in);
109         }
110         public ShellCallback[] newArray(int size) {
111             return new ShellCallback[size];
112         }
113     };
114 }
115