Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a95fe315 authored by Arthur Ishiguro's avatar Arthur Ishiguro
Browse files

Adds ContextHubIntentEvent class

Helper class to parse Intent events.

Bug: 117612105
Test: Compile and flash, verify Intent events can be parsed
      using the class
Change-Id: I1267a1ce0cbbfd56ff9abb059ccc0117f060b7ff
parent 2c87f2ea
Loading
Loading
Loading
Loading
+224 −0
Original line number Diff line number Diff line
/*
 * 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.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 through {@link ContextHubClient.registerIntent(PendingIntent, long)}. This object
 * can only be created through the factory method {@link ContextHubIntentEvent.fromIntent(Intent)}.
 *
 * @hide
 */
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 through {@link ContextHubClient.registerIntent(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 + "]";
    }

    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 */);
    }
}