diff options
author | Justin Klaassen <justinklaassen@google.com> | 2017-09-15 17:58:39 -0400 |
---|---|---|
committer | Justin Klaassen <justinklaassen@google.com> | 2017-09-15 17:58:39 -0400 |
commit | 10d07c88d69cc64f73a069163e7ea5ba2519a099 (patch) | |
tree | 8dbd149eb350320a29c3d10e7ad3201de1c5cbee /android/view/WindowId.java | |
parent | 677516fb6b6f207d373984757d3d9450474b6b00 (diff) | |
download | android-28-10d07c88d69cc64f73a069163e7ea5ba2519a099.tar.gz |
Import Android SDK Platform PI [4335822]
/google/data/ro/projects/android/fetch_artifact \
--bid 4335822 \
--target sdk_phone_armv7-win_sdk \
sdk-repo-linux-sources-4335822.zip
AndroidVersion.ApiLevel has been modified to appear as 28
Change-Id: Ic8f04be005a71c2b9abeaac754d8da8d6f9a2c32
Diffstat (limited to 'android/view/WindowId.java')
-rw-r--r-- | android/view/WindowId.java | 224 |
1 files changed, 224 insertions, 0 deletions
diff --git a/android/view/WindowId.java b/android/view/WindowId.java new file mode 100644 index 00000000..c4cda2c7 --- /dev/null +++ b/android/view/WindowId.java @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2006 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.view; + +import android.os.Handler; +import android.os.IBinder; +import android.os.Message; +import android.os.Parcel; +import android.os.Parcelable; +import android.os.RemoteException; + +import java.util.HashMap; + +/** + * Safe identifier for a window. This currently allows you to retrieve and observe + * the input focus state of the window. Most applications will + * not use this, instead relying on the simpler (and more efficient) methods available + * on {@link View}. This classes is useful when window input interactions need to be + * done across processes: the class itself is a Parcelable that can be passed to other + * processes for them to interact with your window, and it provides a limited safe API + * that doesn't allow the other process to negatively harm your window. + */ +public class WindowId implements Parcelable { + private final IWindowId mToken; + + /** + * Subclass for observing changes to the focus state of an {@link WindowId}. + * You should use the same instance of this class for observing multiple + * {@link WindowId} objects, since this class is fairly heavy-weight -- the + * base class includes all of the mechanisms for connecting to and receiving updates + * from the window. + */ + public static abstract class FocusObserver { + final IWindowFocusObserver.Stub mIObserver = new IWindowFocusObserver.Stub() { + + @Override + public void focusGained(IBinder inputToken) { + WindowId token; + synchronized (mRegistrations) { + token = mRegistrations.get(inputToken); + } + if (mHandler != null) { + mHandler.sendMessage(mHandler.obtainMessage(1, token)); + } else { + onFocusGained(token); + } + } + + @Override + public void focusLost(IBinder inputToken) { + WindowId token; + synchronized (mRegistrations) { + token = mRegistrations.get(inputToken); + } + if (mHandler != null) { + mHandler.sendMessage(mHandler.obtainMessage(2, token)); + } else { + onFocusLost(token); + } + } + }; + + final HashMap<IBinder, WindowId> mRegistrations + = new HashMap<IBinder, WindowId>(); + + class H extends Handler { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case 1: + onFocusGained((WindowId)msg.obj); + break; + case 2: + onFocusLost((WindowId)msg.obj); + break; + default: + super.handleMessage(msg); + } + } + } + + final Handler mHandler; + + /** + * Construct a new observer. This observer will be configured so that all + * of its callbacks are dispatched on the current calling thread. + */ + public FocusObserver() { + mHandler = new H(); + } + + /** + * Called when one of the monitored windows gains input focus. + */ + public abstract void onFocusGained(WindowId token); + + /** + * Called when one of the monitored windows loses input focus. + */ + public abstract void onFocusLost(WindowId token); + } + + /** + * Retrieve the current focus state of the associated window. + */ + public boolean isFocused() { + try { + return mToken.isFocused(); + } catch (RemoteException e) { + return false; + } + } + + /** + * Start monitoring for changes in the focus state of the window. + */ + public void registerFocusObserver(FocusObserver observer) { + synchronized (observer.mRegistrations) { + if (observer.mRegistrations.containsKey(mToken.asBinder())) { + throw new IllegalStateException( + "Focus observer already registered with input token"); + } + observer.mRegistrations.put(mToken.asBinder(), this); + try { + mToken.registerFocusObserver(observer.mIObserver); + } catch (RemoteException e) { + } + } + } + + /** + * Stop monitoring changes in the focus state of the window. + */ + public void unregisterFocusObserver(FocusObserver observer) { + synchronized (observer.mRegistrations) { + if (observer.mRegistrations.remove(mToken.asBinder()) == null) { + throw new IllegalStateException("Focus observer not registered with input token"); + } + try { + mToken.unregisterFocusObserver(observer.mIObserver); + } catch (RemoteException e) { + } + } + } + + /** + * Comparison operator on two IntentSender objects, such that true + * is returned then they both represent the same operation from the + * same package. + */ + @Override + public boolean equals(Object otherObj) { + if (otherObj instanceof WindowId) { + return mToken.asBinder().equals(((WindowId) otherObj) + .mToken.asBinder()); + } + return false; + } + + @Override + public int hashCode() { + return mToken.asBinder().hashCode(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(128); + sb.append("IntentSender{"); + sb.append(Integer.toHexString(System.identityHashCode(this))); + sb.append(": "); + sb.append(mToken != null ? mToken.asBinder() : null); + sb.append('}'); + return sb.toString(); + } + + public int describeContents() { + return 0; + } + + public void writeToParcel(Parcel out, int flags) { + out.writeStrongBinder(mToken.asBinder()); + } + + public static final Parcelable.Creator<WindowId> CREATOR + = new Parcelable.Creator<WindowId>() { + public WindowId createFromParcel(Parcel in) { + IBinder target = in.readStrongBinder(); + return target != null ? new WindowId(target) : null; + } + + public WindowId[] newArray(int size) { + return new WindowId[size]; + } + }; + + /** @hide */ + public IWindowId getTarget() { + return mToken; + } + + /** @hide */ + public WindowId(IWindowId target) { + mToken = target; + } + + /** @hide */ + public WindowId(IBinder target) { + mToken = IWindowId.Stub.asInterface(target); + } +} |