blob: d1190ab28ed5baeb79e714e70b3a6291c303b375 [file] [log] [blame]
/*
* 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;
}
@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 */);
}
}