| /* |
| * Copyright 2018 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.hardware.location; |
| |
| import android.annotation.NonNull; |
| import android.annotation.Nullable; |
| import android.annotation.SystemApi; |
| import android.app.PendingIntent; |
| import android.content.Intent; |
| |
| import com.android.internal.util.Preconditions; |
| |
| /** |
| * A helper class to retrieve information about a Intent event received for a PendingIntent |
| * registered with {@link ContextHubManager.createClient(ContextHubInfo, PendingIntent, long)}. |
| * This object can only be created through the factory method |
| * {@link ContextHubIntentEvent.fromIntent(Intent)}. |
| * |
| * @hide |
| */ |
| @SystemApi |
| public class ContextHubIntentEvent { |
| @ContextHubManager.Event private final int mEventType; |
| |
| @NonNull private final ContextHubInfo mContextHubInfo; |
| |
| private final long mNanoAppId; |
| |
| private final NanoAppMessage mNanoAppMessage; |
| |
| private final int mNanoAppAbortCode; |
| |
| private ContextHubIntentEvent( |
| @NonNull ContextHubInfo contextHubInfo, @ContextHubManager.Event int eventType, |
| long nanoAppId, NanoAppMessage nanoAppMessage, int nanoAppAbortCode) { |
| mContextHubInfo = contextHubInfo; |
| mEventType = eventType; |
| mNanoAppId = nanoAppId; |
| mNanoAppMessage = nanoAppMessage; |
| mNanoAppAbortCode = nanoAppAbortCode; |
| } |
| |
| private ContextHubIntentEvent( |
| @NonNull ContextHubInfo contextHubInfo, @ContextHubManager.Event int eventType) { |
| this(contextHubInfo, eventType, -1 /* nanoAppId */, null /* nanoAppMessage */, |
| -1 /* nanoAppAbortCode */); |
| } |
| |
| private ContextHubIntentEvent( |
| @NonNull ContextHubInfo contextHubInfo, @ContextHubManager.Event int eventType, |
| long nanoAppId) { |
| this(contextHubInfo, eventType, nanoAppId, null /* nanoAppMessage */, |
| -1 /* nanoAppAbortCode */); |
| } |
| |
| private ContextHubIntentEvent( |
| @NonNull ContextHubInfo contextHubInfo, @ContextHubManager.Event int eventType, |
| long nanoAppId, @NonNull NanoAppMessage nanoAppMessage) { |
| this(contextHubInfo, eventType, nanoAppId, nanoAppMessage, -1 /* nanoAppAbortCode */); |
| } |
| |
| private ContextHubIntentEvent( |
| @NonNull ContextHubInfo contextHubInfo, @ContextHubManager.Event int eventType, |
| long nanoAppId, int nanoAppAbortCode) { |
| this(contextHubInfo, eventType, nanoAppId, null /* nanoAppMessage */, nanoAppAbortCode); |
| } |
| |
| /** |
| * Creates a ContextHubIntentEvent object from an Intent received through a PendingIntent |
| * registered with {@link ContextHubManager.createClient(ContextHubInfo, PendingIntent, long)}. |
| * |
| * @param intent the Intent object from an Intent event |
| * @return the ContextHubIntentEvent object describing the event |
| * |
| * @throws IllegalArgumentException if the Intent was not a valid intent |
| */ |
| @NonNull |
| public static ContextHubIntentEvent fromIntent(@NonNull Intent intent) { |
| Preconditions.checkNotNull(intent, "Intent cannot be null"); |
| |
| hasExtraOrThrow(intent, ContextHubManager.EXTRA_CONTEXT_HUB_INFO); |
| ContextHubInfo info = intent.getParcelableExtra(ContextHubManager.EXTRA_CONTEXT_HUB_INFO); |
| if (info == null) { |
| throw new IllegalArgumentException("ContextHubInfo extra was null"); |
| } |
| |
| int eventType = getIntExtraOrThrow(intent, ContextHubManager.EXTRA_EVENT_TYPE); |
| ContextHubIntentEvent event; |
| switch (eventType) { |
| case ContextHubManager.EVENT_NANOAPP_LOADED: |
| case ContextHubManager.EVENT_NANOAPP_UNLOADED: |
| case ContextHubManager.EVENT_NANOAPP_ENABLED: |
| case ContextHubManager.EVENT_NANOAPP_DISABLED: |
| case ContextHubManager.EVENT_NANOAPP_ABORTED: |
| case ContextHubManager.EVENT_NANOAPP_MESSAGE: // fall through |
| long nanoAppId = getLongExtraOrThrow(intent, ContextHubManager.EXTRA_NANOAPP_ID); |
| if (eventType == ContextHubManager.EVENT_NANOAPP_MESSAGE) { |
| hasExtraOrThrow(intent, ContextHubManager.EXTRA_MESSAGE); |
| NanoAppMessage message = |
| intent.getParcelableExtra(ContextHubManager.EXTRA_MESSAGE); |
| if (message == null) { |
| throw new IllegalArgumentException("NanoAppMessage extra was null"); |
| } |
| |
| event = new ContextHubIntentEvent(info, eventType, nanoAppId, message); |
| } else if (eventType == ContextHubManager.EVENT_NANOAPP_ABORTED) { |
| int nanoAppAbortCode = getIntExtraOrThrow( |
| intent, ContextHubManager.EXTRA_NANOAPP_ABORT_CODE); |
| event = new ContextHubIntentEvent(info, eventType, nanoAppId, nanoAppAbortCode); |
| } else { |
| event = new ContextHubIntentEvent(info, eventType, nanoAppId); |
| } |
| break; |
| |
| case ContextHubManager.EVENT_HUB_RESET: |
| event = new ContextHubIntentEvent(info, eventType); |
| break; |
| |
| default: |
| throw new IllegalArgumentException("Unknown intent event type " + eventType); |
| } |
| |
| return event; |
| } |
| |
| /** |
| * @return the event type of this Intent event |
| */ |
| @ContextHubManager.Event |
| public int getEventType() { |
| return mEventType; |
| } |
| |
| /** |
| * @return the ContextHubInfo object describing the Context Hub this event was for |
| */ |
| @NonNull |
| public ContextHubInfo getContextHubInfo() { |
| return mContextHubInfo; |
| } |
| |
| /** |
| * @return the ID of the nanoapp this event was for |
| * |
| * @throws UnsupportedOperationException if the event did not have a nanoapp associated |
| */ |
| public long getNanoAppId() { |
| if (mEventType == ContextHubManager.EVENT_HUB_RESET) { |
| throw new UnsupportedOperationException( |
| "Cannot invoke getNanoAppId() on Context Hub reset event"); |
| } |
| return mNanoAppId; |
| } |
| |
| /** |
| * @return the nanoapp's abort code |
| * |
| * @throws UnsupportedOperationException if this was not a nanoapp abort event |
| */ |
| public int getNanoAppAbortCode() { |
| if (mEventType != ContextHubManager.EVENT_NANOAPP_ABORTED) { |
| throw new UnsupportedOperationException( |
| "Cannot invoke getNanoAppAbortCode() on non-abort event: " + mEventType); |
| } |
| return mNanoAppAbortCode; |
| } |
| |
| /** |
| * @return the message from a nanoapp |
| * |
| * @throws UnsupportedOperationException if this was not a nanoapp message event |
| */ |
| @NonNull |
| public NanoAppMessage getNanoAppMessage() { |
| if (mEventType != ContextHubManager.EVENT_NANOAPP_MESSAGE) { |
| throw new UnsupportedOperationException( |
| "Cannot invoke getNanoAppMessage() on non-message event: " + mEventType); |
| } |
| return mNanoAppMessage; |
| } |
| |
| @NonNull |
| @Override |
| public String toString() { |
| String out = "ContextHubIntentEvent[eventType = " + mEventType |
| + ", contextHubId = " + mContextHubInfo.getId(); |
| |
| if (mEventType != ContextHubManager.EVENT_HUB_RESET) { |
| out += ", nanoAppId = 0x" + Long.toHexString(mNanoAppId); |
| } |
| if (mEventType == ContextHubManager.EVENT_NANOAPP_ABORTED) { |
| out += ", nanoAppAbortCode = " + mNanoAppAbortCode; |
| } |
| if (mEventType == ContextHubManager.EVENT_NANOAPP_MESSAGE) { |
| out += ", nanoAppMessage = " + mNanoAppMessage; |
| } |
| |
| return out + "]"; |
| } |
| |
| @Override |
| public boolean equals(@Nullable Object object) { |
| if (object == this) { |
| return true; |
| } |
| |
| boolean isEqual = false; |
| if (object instanceof ContextHubIntentEvent) { |
| ContextHubIntentEvent other = (ContextHubIntentEvent) object; |
| if (other.getEventType() == mEventType |
| && other.getContextHubInfo().equals(mContextHubInfo)) { |
| isEqual = true; |
| try { |
| if (mEventType != ContextHubManager.EVENT_HUB_RESET) { |
| isEqual &= (other.getNanoAppId() == mNanoAppId); |
| } |
| if (mEventType == ContextHubManager.EVENT_NANOAPP_ABORTED) { |
| isEqual &= (other.getNanoAppAbortCode() == mNanoAppAbortCode); |
| } |
| if (mEventType == ContextHubManager.EVENT_NANOAPP_MESSAGE) { |
| isEqual &= other.getNanoAppMessage().equals(mNanoAppMessage); |
| } |
| } catch (UnsupportedOperationException e) { |
| isEqual = false; |
| } |
| } |
| } |
| |
| return isEqual; |
| } |
| |
| private static void hasExtraOrThrow(Intent intent, String extra) { |
| if (!intent.hasExtra(extra)) { |
| throw new IllegalArgumentException("Intent did not have extra: " + extra); |
| } |
| } |
| |
| private static int getIntExtraOrThrow(Intent intent, String extra) { |
| hasExtraOrThrow(intent, extra); |
| return intent.getIntExtra(extra, -1 /* defaultValue */); |
| } |
| |
| private static long getLongExtraOrThrow(Intent intent, String extra) { |
| hasExtraOrThrow(intent, extra); |
| return intent.getLongExtra(extra, -1 /* defaultValue */); |
| } |
| } |