Home | History | Annotate | Download | only in os
      1 /*
      2  * Copyright (C) 2018 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.annotation.NonNull;
     20 import android.media.AudioAttributes;
     21 import android.util.Slog;
     22 
     23 import com.android.internal.util.Preconditions;
     24 
     25 /**
     26  * An ExternalVibration represents an on-going vibration being controlled by something other than
     27  * the core vibrator service.
     28  *
     29  * @hide
     30  */
     31 public class ExternalVibration implements Parcelable {
     32     private static final String TAG = "ExternalVibration";
     33     private int mUid;
     34     @NonNull
     35     private String mPkg;
     36     @NonNull
     37     private AudioAttributes mAttrs;
     38     @NonNull
     39     private IExternalVibrationController mController;
     40     // A token used to maintain equality comparisons when passing objects across process
     41     // boundaries.
     42     @NonNull
     43     private IBinder mToken;
     44 
     45     public ExternalVibration(int uid, @NonNull String pkg, @NonNull AudioAttributes attrs,
     46             @NonNull IExternalVibrationController controller) {
     47         mUid = uid;
     48         mPkg = Preconditions.checkNotNull(pkg);
     49         mAttrs = Preconditions.checkNotNull(attrs);
     50         mController = Preconditions.checkNotNull(controller);
     51         mToken = new Binder();
     52     }
     53 
     54     private ExternalVibration(Parcel in) {
     55         mUid = in.readInt();
     56         mPkg = in.readString();
     57         mAttrs = readAudioAttributes(in);
     58         mController = IExternalVibrationController.Stub.asInterface(in.readStrongBinder());
     59         mToken = in.readStrongBinder();
     60     }
     61 
     62     private AudioAttributes readAudioAttributes(Parcel in) {
     63         int usage = in.readInt();
     64         int contentType = in.readInt();
     65         int capturePreset = in.readInt();
     66         int flags = in.readInt();
     67         AudioAttributes.Builder builder = new AudioAttributes.Builder();
     68         return builder.setUsage(usage)
     69                 .setContentType(contentType)
     70                 .setCapturePreset(capturePreset)
     71                 .setFlags(flags)
     72                 .build();
     73     }
     74 
     75     public int getUid() {
     76         return mUid;
     77     }
     78 
     79     public String getPackage() {
     80         return mPkg;
     81     }
     82 
     83     public AudioAttributes getAudioAttributes() {
     84         return mAttrs;
     85     }
     86 
     87     /**
     88      * Mutes the external vibration if it's playing and unmuted.
     89      *
     90      * @return whether the muting operation was successful
     91      */
     92     public boolean mute() {
     93         try {
     94             mController.mute();
     95         } catch (RemoteException e) {
     96             Slog.wtf(TAG, "Failed to mute vibration stream: " + this, e);
     97             return false;
     98         }
     99         return true;
    100     }
    101 
    102     /**
    103      * Unmutes the external vibration if it's playing and muted.
    104      *
    105      * @return whether the unmuting operation was successful
    106      */
    107     public boolean unmute() {
    108         try {
    109             mController.unmute();
    110         } catch (RemoteException e) {
    111             Slog.wtf(TAG, "Failed to unmute vibration stream: " + this, e);
    112             return false;
    113         }
    114         return true;
    115     }
    116 
    117     /**
    118      * Links a recipient to death against this external vibration token
    119      */
    120     public void linkToDeath(IBinder.DeathRecipient recipient) {
    121         try {
    122             mToken.linkToDeath(recipient, 0);
    123         } catch (RemoteException e) {
    124             return;
    125         }
    126     }
    127 
    128     /**
    129      * Unlinks a recipient to death against this external vibration token
    130      */
    131     public void unlinkToDeath(IBinder.DeathRecipient recipient) {
    132         mToken.unlinkToDeath(recipient, 0);
    133     }
    134 
    135     @Override
    136     public boolean equals(Object o) {
    137         if (o == null || !(o instanceof ExternalVibration)) {
    138             return false;
    139         }
    140         ExternalVibration other = (ExternalVibration) o;
    141         return mToken.equals(other.mToken);
    142     }
    143 
    144     @Override
    145     public String toString() {
    146         return "ExternalVibration{"
    147             + "uid=" + mUid + ", "
    148             + "pkg=" + mPkg + ", "
    149             + "attrs=" + mAttrs + ", "
    150             + "controller=" + mController
    151             + "token=" + mController
    152             + "}";
    153     }
    154 
    155     @Override
    156     public void writeToParcel(Parcel out, int flags) {
    157         out.writeInt(mUid);
    158         out.writeString(mPkg);
    159         writeAudioAttributes(mAttrs, out, flags);
    160         out.writeParcelable(mAttrs, flags);
    161         out.writeStrongBinder(mController.asBinder());
    162         out.writeStrongBinder(mToken);
    163     }
    164 
    165     private static void writeAudioAttributes(AudioAttributes attrs, Parcel out, int flags) {
    166         out.writeInt(attrs.getUsage());
    167         out.writeInt(attrs.getContentType());
    168         out.writeInt(attrs.getCapturePreset());
    169         out.writeInt(attrs.getAllFlags());
    170     }
    171 
    172     @Override
    173     public int describeContents() {
    174         return 0;
    175     }
    176 
    177     public static final @android.annotation.NonNull Parcelable.Creator<ExternalVibration> CREATOR =
    178             new Parcelable.Creator<ExternalVibration>() {
    179                 @Override
    180                 public ExternalVibration createFromParcel(Parcel in) {
    181                     return new ExternalVibration(in);
    182                 }
    183 
    184                 @Override
    185                 public ExternalVibration[] newArray(int size) {
    186                     return new ExternalVibration[size];
    187                 }
    188             };
    189 }
    190