blob: 632f6c8694ce99a536a668ec469882a14018581a [file] [log] [blame]
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.os;
import android.util.Log;
import com.android.internal.os.IShellCallback;
/**
* Special-purpose API for use with {@link IBinder#shellCommand IBinder.shellCommand} for
* performing operations back on the invoking shell.
* @hide
*/
public class ShellCallback implements Parcelable {
final static String TAG = "ShellCallback";
final static boolean DEBUG = false;
final boolean mLocal;
IShellCallback mShellCallback;
class MyShellCallback extends IShellCallback.Stub {
public ParcelFileDescriptor openFile(String path, String seLinuxContext,
String mode) {
return onOpenFile(path, seLinuxContext, mode);
}
}
/**
* Create a new ShellCallback to receive requests.
*/
public ShellCallback() {
mLocal = true;
}
/**
* Ask the shell to open a file. If opening for writing, will truncate the file if it
* already exists and will create the file if it doesn't exist.
* @param path Path of the file to be opened/created.
* @param seLinuxContext Optional SELinux context that must be allowed to have
* access to the file; if null, nothing is required.
* @param mode Mode to open file in: "r" for input/reading an existing file,
* "r+" for reading/writing an existing file, "w" for output/writing a new file (either
* creating or truncating an existing one), "w+" for reading/writing a new file (either
* creating or truncating an existing one).
*/
public ParcelFileDescriptor openFile(String path, String seLinuxContext, String mode) {
if (DEBUG) Log.d(TAG, "openFile " + this + " mode=" + mode + ": mLocal=" + mLocal
+ " mShellCallback=" + mShellCallback);
if (mLocal) {
return onOpenFile(path, seLinuxContext, mode);
}
if (mShellCallback != null) {
try {
return mShellCallback.openFile(path, seLinuxContext, mode);
} catch (RemoteException e) {
Log.w(TAG, "Failure opening " + path, e);
}
}
return null;
}
public ParcelFileDescriptor onOpenFile(String path, String seLinuxContext, String mode) {
return null;
}
public static void writeToParcel(ShellCallback callback, Parcel out) {
if (callback == null) {
out.writeStrongBinder(null);
} else {
callback.writeToParcel(out, 0);
}
}
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel out, int flags) {
synchronized (this) {
if (mShellCallback == null) {
mShellCallback = new MyShellCallback();
}
out.writeStrongBinder(mShellCallback.asBinder());
}
}
ShellCallback(Parcel in) {
mLocal = false;
mShellCallback = IShellCallback.Stub.asInterface(in.readStrongBinder());
if (mShellCallback != null) {
Binder.allowBlocking(mShellCallback.asBinder());
}
}
public static final @android.annotation.NonNull Parcelable.Creator<ShellCallback> CREATOR
= new Parcelable.Creator<ShellCallback>() {
public ShellCallback createFromParcel(Parcel in) {
return new ShellCallback(in);
}
public ShellCallback[] newArray(int size) {
return new ShellCallback[size];
}
};
}