Merge "Implement remaining ITunerCallback methods."

This commit is contained in:
Tomasz Wasilczyk
2017-06-13 15:42:20 +00:00
committed by Android (Google) Code Review
9 changed files with 207 additions and 33 deletions

View File

@@ -714,6 +714,7 @@ aidl_files := \
frameworks/base/core/java/android/print/PrintJobId.aidl \
frameworks/base/core/java/android/printservice/recommendation/RecommendationInfo.aidl \
frameworks/base/core/java/android/hardware/radio/RadioManager.aidl \
frameworks/base/core/java/android/hardware/radio/RadioMetadata.aidl \
frameworks/base/core/java/android/hardware/usb/UsbDevice.aidl \
frameworks/base/core/java/android/hardware/usb/UsbInterface.aidl \
frameworks/base/core/java/android/hardware/usb/UsbEndpoint.aidl \

View File

@@ -17,10 +17,18 @@
package android.hardware.radio;
import android.hardware.radio.RadioManager;
import android.hardware.radio.RadioMetadata;
/** {@hide} */
oneway interface ITunerCallback {
void onError(int status);
void onConfigurationChanged(in RadioManager.BandConfig config);
void onProgramInfoChanged(in RadioManager.ProgramInfo info);
void onMetadataChanged(in RadioMetadata metadata);
void onTrafficAnnouncement(boolean active);
void onEmergencyAnnouncement(boolean active);
void onAntennaState(boolean connected);
void onBackgroundScanAvailabilityChange(boolean isAvailable);
void onBackgroundScanComplete();
void onProgramListChanged();
}

View File

@@ -0,0 +1,20 @@
/**
* Copyright (C) 2017 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.radio;
/** @hide */
parcelable RadioMetadata;

View File

@@ -19,14 +19,9 @@ package android.hardware.radio;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import java.lang.ref.WeakReference;
import java.util.List;
import java.util.UUID;
/**
* RadioTuner interface provides methods to control a radio tuner on the device: selecting and
@@ -303,6 +298,16 @@ public abstract class RadioTuner {
public static final int ERROR_SCAN_TIMEOUT = 3;
/** The requested configuration could not be applied */
public static final int ERROR_CONFIG = 4;
/**
* Background scan was interrupted due to hardware becoming temporarily unavailable.
* @hide FutureFeature
*/
public static final int ERROR_BACKGROUND_SCAN_UNAVAILABLE = 5;
/**
* Background scan failed due to other error, ie. HW failure.
* @hide FutureFeature
*/
public static final int ERROR_BACKGROUND_SCAN_FAILED = 6;
/**
* Callback provided by the client application when opening a {@link RadioTuner}

View File

@@ -51,4 +51,39 @@ class TunerCallbackAdapter extends ITunerCallback.Stub {
public void onProgramInfoChanged(RadioManager.ProgramInfo info) {
mHandler.post(() -> mCallback.onProgramInfoChanged(info));
}
@Override
public void onMetadataChanged(RadioMetadata metadata) {
mHandler.post(() -> mCallback.onMetadataChanged(metadata));
}
@Override
public void onTrafficAnnouncement(boolean active) {
mHandler.post(() -> mCallback.onTrafficAnnouncement(active));
}
@Override
public void onEmergencyAnnouncement(boolean active) {
mHandler.post(() -> mCallback.onEmergencyAnnouncement(active));
}
@Override
public void onAntennaState(boolean connected) {
mHandler.post(() -> mCallback.onAntennaState(connected));
}
@Override
public void onBackgroundScanAvailabilityChange(boolean isAvailable) {
mHandler.post(() -> mCallback.onBackgroundScanAvailabilityChange(isAvailable));
}
@Override
public void onBackgroundScanComplete() {
mHandler.post(() -> mCallback.onBackgroundScanComplete());
}
@Override
public void onProgramListChanged() {
mHandler.post(() -> mCallback.onProgramListChanged());
}
}

View File

@@ -20,6 +20,7 @@ import android.annotation.NonNull;
import android.hardware.radio.ITuner;
import android.hardware.radio.ITunerCallback;
import android.hardware.radio.RadioManager;
import android.hardware.radio.RadioMetadata;
import android.hardware.radio.RadioTuner;
import android.os.IBinder;
import android.os.RemoteException;
@@ -57,6 +58,18 @@ class TunerCallback implements ITunerCallback {
nativeDetach(mNativeContext);
}
private interface RunnableThrowingRemoteException {
void run() throws RemoteException;
}
private void dispatch(RunnableThrowingRemoteException func) {
try {
func.run();
} catch (RemoteException e) {
Slog.e(TAG, "client died", e);
}
}
// called from native side
private void handleHwFailure() {
onError(RadioTuner.ERROR_HARDWARE_FAILURE);
@@ -65,29 +78,52 @@ class TunerCallback implements ITunerCallback {
@Override
public void onError(int status) {
try {
mClientCallback.onError(status);
} catch (RemoteException e) {
Slog.e(TAG, "client died", e);
}
dispatch(() -> mClientCallback.onError(status));
}
@Override
public void onConfigurationChanged(RadioManager.BandConfig config) {
try {
mClientCallback.onConfigurationChanged(config);
} catch (RemoteException e) {
Slog.e(TAG, "client died", e);
}
dispatch(() -> mClientCallback.onConfigurationChanged(config));
}
@Override
public void onProgramInfoChanged(RadioManager.ProgramInfo info) {
try {
mClientCallback.onProgramInfoChanged(info);
} catch (RemoteException e) {
Slog.e(TAG, "client died", e);
}
dispatch(() -> mClientCallback.onProgramInfoChanged(info));
}
@Override
public void onMetadataChanged(RadioMetadata metadata) {
dispatch(() -> mClientCallback.onMetadataChanged(metadata));
}
@Override
public void onTrafficAnnouncement(boolean active) {
dispatch(() -> mClientCallback.onTrafficAnnouncement(active));
}
@Override
public void onEmergencyAnnouncement(boolean active) {
dispatch(() -> mClientCallback.onEmergencyAnnouncement(active));
}
@Override
public void onAntennaState(boolean connected) {
dispatch(() -> mClientCallback.onAntennaState(connected));
}
@Override
public void onBackgroundScanAvailabilityChange(boolean isAvailable) {
dispatch(() -> mClientCallback.onBackgroundScanAvailabilityChange(isAvailable));
}
@Override
public void onBackgroundScanComplete() {
dispatch(() -> mClientCallback.onBackgroundScanComplete());
}
@Override
public void onProgramListChanged() {
dispatch(() -> mClientCallback.onProgramListChanged());
}
@Override

View File

@@ -53,6 +53,13 @@ static struct {
jmethodID onError;
jmethodID onConfigurationChanged;
jmethodID onProgramInfoChanged;
jmethodID onMetadataChanged;
jmethodID onTrafficAnnouncement;
jmethodID onEmergencyAnnouncement;
jmethodID onAntennaState;
jmethodID onBackgroundScanAvailabilityChange;
jmethodID onBackgroundScanComplete;
jmethodID onProgramListChanged;
} TunerCallback;
} gjni;
@@ -63,6 +70,8 @@ enum class TunerError : jint {
CANCELLED = 2,
SCAN_TIMEOUT = 3,
CONFIG = 4,
BACKGROUND_SCAN_UNAVAILABLE = 5,
BACKGROUND_SCAN_FAILED = 6,
};
static Mutex gContextMutex;
@@ -191,48 +200,93 @@ Return<void> NativeCallback::tuneComplete_1_1(Result result, const V1_1::Program
}
Return<void> NativeCallback::afSwitch(const V1_0::ProgramInfo& info) {
ALOGE("Not implemented: afSwitch");
return Return<void>();
ALOGV("afSwitch()");
return tuneComplete(Result::OK, info);
}
Return<void> NativeCallback::afSwitch_1_1(const V1_1::ProgramInfo& info) {
ALOGE("Not implemented: afSwitch_1_1");
return Return<void>();
ALOGV("afSwitch_1_1()");
return tuneComplete_1_1(Result::OK, info);
}
Return<void> NativeCallback::antennaStateChange(bool connected) {
ALOGE("Not implemented: antennaStateChange");
ALOGV("antennaStateChange(%d)", connected);
mCallbackThread.enqueue([this, connected](JNIEnv *env) {
env->CallVoidMethod(mJCallback, gjni.TunerCallback.onAntennaState, connected);
});
return Return<void>();
}
Return<void> NativeCallback::trafficAnnouncement(bool active) {
ALOGE("Not implemented: trafficAnnouncement");
ALOGV("trafficAnnouncement(%d)", active);
mCallbackThread.enqueue([this, active](JNIEnv *env) {
env->CallVoidMethod(mJCallback, gjni.TunerCallback.onTrafficAnnouncement, active);
});
return Return<void>();
}
Return<void> NativeCallback::emergencyAnnouncement(bool active) {
ALOGE("Not implemented: emergencyAnnouncement");
ALOGV("emergencyAnnouncement(%d)", active);
mCallbackThread.enqueue([this, active](JNIEnv *env) {
env->CallVoidMethod(mJCallback, gjni.TunerCallback.onEmergencyAnnouncement, active);
});
return Return<void>();
}
Return<void> NativeCallback::newMetadata(uint32_t channel, uint32_t subChannel,
const hidl_vec<MetaData>& metadata) {
ALOGE("Not implemented: newMetadata");
// channel and subChannel are not used
ALOGV("newMetadata(%d, %d)", channel, subChannel);
mCallbackThread.enqueue([this, metadata](JNIEnv *env) {
auto jMetadata = convert::MetadataFromHal(env, metadata);
if (jMetadata == nullptr) return;
env->CallVoidMethod(mJCallback, gjni.TunerCallback.onMetadataChanged, jMetadata.get());
});
return Return<void>();
}
Return<void> NativeCallback::backgroundScanAvailable(bool isAvailable) {
ALOGE("Not implemented: backgroundScanAvailable");
ALOGV("backgroundScanAvailable(%d)", isAvailable);
mCallbackThread.enqueue([this, isAvailable](JNIEnv *env) {
env->CallVoidMethod(mJCallback,
gjni.TunerCallback.onBackgroundScanAvailabilityChange, isAvailable);
});
return Return<void>();
}
Return<void> NativeCallback::backgroundScanComplete(ProgramListResult result) {
ALOGE("Not implemented: backgroundScanComplete");
ALOGV("backgroundScanComplete(%d)", result);
mCallbackThread.enqueue([this, result](JNIEnv *env) {
if (result == ProgramListResult::OK) {
env->CallVoidMethod(mJCallback, gjni.TunerCallback.onBackgroundScanComplete);
} else {
auto cause = (result == ProgramListResult::UNAVAILABLE) ?
TunerError::BACKGROUND_SCAN_UNAVAILABLE : TunerError::BACKGROUND_SCAN_FAILED;
env->CallVoidMethod(mJCallback, gjni.TunerCallback.onError, cause);
}
});
return Return<void>();
}
Return<void> NativeCallback::programListChanged() {
ALOGE("Not implemented: programListChanged");
ALOGV("programListChanged()");
mCallbackThread.enqueue([this](JNIEnv *env) {
env->CallVoidMethod(mJCallback, gjni.TunerCallback.onProgramListChanged);
});
return Return<void>();
}
@@ -310,6 +364,20 @@ void register_android_server_radio_TunerCallback(JavaVM *vm, JNIEnv *env) {
"onConfigurationChanged", "(Landroid/hardware/radio/RadioManager$BandConfig;)V");
gjni.TunerCallback.onProgramInfoChanged = GetMethodIDOrDie(env, tunerCbClass,
"onProgramInfoChanged", "(Landroid/hardware/radio/RadioManager$ProgramInfo;)V");
gjni.TunerCallback.onMetadataChanged = GetMethodIDOrDie(env, tunerCbClass,
"onMetadataChanged", "(Landroid/hardware/radio/RadioMetadata;)V");
gjni.TunerCallback.onTrafficAnnouncement = GetMethodIDOrDie(env, tunerCbClass,
"onTrafficAnnouncement", "(Z)V");
gjni.TunerCallback.onEmergencyAnnouncement = GetMethodIDOrDie(env, tunerCbClass,
"onEmergencyAnnouncement", "(Z)V");
gjni.TunerCallback.onAntennaState = GetMethodIDOrDie(env, tunerCbClass,
"onAntennaState", "(Z)V");
gjni.TunerCallback.onBackgroundScanAvailabilityChange = GetMethodIDOrDie(env, tunerCbClass,
"onBackgroundScanAvailabilityChange", "(Z)V");
gjni.TunerCallback.onBackgroundScanComplete = GetMethodIDOrDie(env, tunerCbClass,
"onBackgroundScanComplete", "()V");
gjni.TunerCallback.onProgramListChanged = GetMethodIDOrDie(env, tunerCbClass,
"onProgramListChanged", "()V");
auto res = jniRegisterNativeMethods(env, "com/android/server/radio/TunerCallback",
gTunerCallbackMethods, NELEM(gTunerCallbackMethods));

View File

@@ -254,7 +254,7 @@ Direction DirectionToHal(bool directionDown) {
return directionDown ? Direction::DOWN : Direction::UP;
}
static JavaRef<jobject> MetadataFromHal(JNIEnv *env, const hidl_vec<V1_0::MetaData> metadata) {
JavaRef<jobject> MetadataFromHal(JNIEnv *env, const hidl_vec<V1_0::MetaData> &metadata) {
ALOGV("MetadataFromHal()");
EnvWrapper wrap(env);

View File

@@ -39,6 +39,7 @@ V1_0::BandConfig BandConfigToHal(JNIEnv *env, jobject jConfig, Region &region);
V1_0::Direction DirectionToHal(bool directionDown);
JavaRef<jobject> MetadataFromHal(JNIEnv *env, const hardware::hidl_vec<V1_0::MetaData> &metadata);
JavaRef<jobject> ProgramInfoFromHal(JNIEnv *env, const V1_0::ProgramInfo &info);
JavaRef<jobject> ProgramInfoFromHal(JNIEnv *env, const V1_1::ProgramInfo &info);