• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {
openFile(String path, String seLinuxContext, String mode)38         public ParcelFileDescriptor openFile(String path, String seLinuxContext,
39                 String mode) {
40             return onOpenFile(path, seLinuxContext, mode);
41         }
42     }
43 
44     /**
45      * Create a new ShellCallback to receive requests.
46      */
ShellCallback()47     public ShellCallback() {
48         mLocal = true;
49     }
50 
51     /**
52      * Ask the shell to open a file.  If opening for writing, will truncate the file if it
53      * already exists and will create the file if it doesn't exist.
54      * @param path Path of the file to be opened/created.
55      * @param seLinuxContext Optional SELinux context that must be allowed to have
56      * access to the file; if null, nothing is required.
57      * @param mode Mode to open file in: "r" for input/reading an existing file,
58      * "r+" for reading/writing an existing file, "w" for output/writing a new file (either
59      * creating or truncating an existing one), "w+" for reading/writing a new file (either
60      * creating or truncating an existing one).
61      */
openFile(String path, String seLinuxContext, String mode)62     public ParcelFileDescriptor openFile(String path, String seLinuxContext, String mode) {
63         if (DEBUG) Log.d(TAG, "openFile " + this + " mode=" + mode + ": mLocal=" + mLocal
64                 + " mShellCallback=" + mShellCallback);
65 
66         if (mLocal) {
67             return onOpenFile(path, seLinuxContext, mode);
68         }
69 
70         if (mShellCallback != null) {
71             try {
72                 return mShellCallback.openFile(path, seLinuxContext, mode);
73             } catch (RemoteException e) {
74                 Log.w(TAG, "Failure opening " + path, e);
75             }
76         }
77         return null;
78     }
79 
onOpenFile(String path, String seLinuxContext, String mode)80     public ParcelFileDescriptor onOpenFile(String path, String seLinuxContext, String mode) {
81         return null;
82     }
83 
writeToParcel(ShellCallback callback, Parcel out)84     public static void writeToParcel(ShellCallback callback, Parcel out) {
85         if (callback == null) {
86             out.writeStrongBinder(null);
87         } else {
88             callback.writeToParcel(out, 0);
89         }
90     }
91 
describeContents()92     public int describeContents() {
93         return 0;
94     }
95 
writeToParcel(Parcel out, int flags)96     public void writeToParcel(Parcel out, int flags) {
97         synchronized (this) {
98             if (mShellCallback == null) {
99                 mShellCallback = new MyShellCallback();
100             }
101             out.writeStrongBinder(mShellCallback.asBinder());
102         }
103     }
104 
getShellCallbackBinder()105     public IBinder getShellCallbackBinder() {
106         return mShellCallback.asBinder();
107     }
108 
ShellCallback(Parcel in)109     ShellCallback(Parcel in) {
110         mLocal = false;
111         mShellCallback = IShellCallback.Stub.asInterface(in.readStrongBinder());
112         if (mShellCallback != null) {
113             Binder.allowBlocking(mShellCallback.asBinder());
114         }
115     }
116 
117     public static final @android.annotation.NonNull Parcelable.Creator<ShellCallback> CREATOR
118             = new Parcelable.Creator<ShellCallback>() {
119         public ShellCallback createFromParcel(Parcel in) {
120             return new ShellCallback(in);
121         }
122         public ShellCallback[] newArray(int size) {
123             return new ShellCallback[size];
124         }
125     };
126 }
127