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