1354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn/*
2354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn * Copyright (C) 2016 The Android Open Source Project
3354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn *
4354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License");
5354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn * you may not use this file except in compliance with the License.
6354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn * You may obtain a copy of the License at
7354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn *
8354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn *      http://www.apache.org/licenses/LICENSE-2.0
9354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn *
10354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn * Unless required by applicable law or agreed to in writing, software
11354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS,
12354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn * See the License for the specific language governing permissions and
14354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn * limitations under the License.
15354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn */
16354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn
17354736e196ff79962b3ddb52619a674044d773e2Dianne Hackbornpackage android.os;
18354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn
19354736e196ff79962b3ddb52619a674044d773e2Dianne Hackbornimport android.util.Log;
20354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn
21354736e196ff79962b3ddb52619a674044d773e2Dianne Hackbornimport com.android.internal.os.IShellCallback;
22354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn
23354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn/**
24354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn * Special-purpose API for use with {@link IBinder#shellCommand IBinder.shellCommand} for
25354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn * performing operations back on the invoking shell.
26354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn * @hide
27354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn */
28354736e196ff79962b3ddb52619a674044d773e2Dianne Hackbornpublic class ShellCallback implements Parcelable {
29354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn    final static String TAG = "ShellCallback";
30354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn
31354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn    final static boolean DEBUG = false;
32354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn
33354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn    final boolean mLocal;
34354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn
35354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn    IShellCallback mShellCallback;
36354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn
37354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn    class MyShellCallback extends IShellCallback.Stub {
38354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn        public ParcelFileDescriptor openOutputFile(String path, String seLinuxContext) {
39354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn            return onOpenOutputFile(path, seLinuxContext);
40354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn        }
41354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn    }
42354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn
43354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn    /**
44354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn     * Create a new ShellCallback to receive requests.
45354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn     */
46354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn    public ShellCallback() {
47354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn        mLocal = true;
48354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn    }
49354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn
50354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn    /**
51354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn     * Ask the shell to open a file for writing.  This will truncate the file if it
52354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn     * already exists.  It will create the file if it doesn't exist.
53354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn     * @param path Path of the file to be opened/created.
54354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn     * @param seLinuxContext Optional SELinux context that must be allowed to have
55354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn     * access to the file; if null, nothing is required.
56354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn     */
57354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn    public ParcelFileDescriptor openOutputFile(String path, String seLinuxContext) {
58354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn        if (DEBUG) Log.d(TAG, "openOutputFile " + this + ": mLocal=" + mLocal
59354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn                + " mShellCallback=" + mShellCallback);
60354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn
61354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn        if (mLocal) {
62354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn            return onOpenOutputFile(path, seLinuxContext);
63354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn        }
64354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn
65354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn        if (mShellCallback != null) {
66354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn            try {
67354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn                return mShellCallback.openOutputFile(path, seLinuxContext);
68354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn            } catch (RemoteException e) {
69354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn                Log.w(TAG, "Failure opening " + path, e);
70354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn            }
71354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn        }
72354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn        return null;
73354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn    }
74354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn
75354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn    public ParcelFileDescriptor onOpenOutputFile(String path, String seLinuxContext) {
76354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn        return null;
77354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn    }
78354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn
79354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn    public static void writeToParcel(ShellCallback callback, Parcel out) {
80354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn        if (callback == null) {
81354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn            out.writeStrongBinder(null);
82354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn        } else {
83354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn            callback.writeToParcel(out, 0);
84354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn        }
85354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn    }
86354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn
87354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn    public int describeContents() {
88354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn        return 0;
89354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn    }
90354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn
91354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn    public void writeToParcel(Parcel out, int flags) {
92354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn        synchronized (this) {
93354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn            if (mShellCallback == null) {
94354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn                mShellCallback = new MyShellCallback();
95354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn            }
96354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn            out.writeStrongBinder(mShellCallback.asBinder());
97354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn        }
98354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn    }
99354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn
100354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn    ShellCallback(Parcel in) {
101354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn        mLocal = false;
102354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn        mShellCallback = IShellCallback.Stub.asInterface(in.readStrongBinder());
103354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn    }
104354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn
105354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn    public static final Parcelable.Creator<ShellCallback> CREATOR
106354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn            = new Parcelable.Creator<ShellCallback>() {
107354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn        public ShellCallback createFromParcel(Parcel in) {
108354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn            return new ShellCallback(in);
109354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn        }
110354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn        public ShellCallback[] newArray(int size) {
111354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn            return new ShellCallback[size];
112354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn        }
113354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn    };
114354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn}
115