| /* |
| * Copyright (C) 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 com.android.car.radio; |
| |
| import android.car.Car; |
| import android.content.Intent; |
| import android.graphics.drawable.Drawable; |
| import android.os.Bundle; |
| import android.view.KeyEvent; |
| |
| import androidx.annotation.NonNull; |
| import androidx.fragment.app.FragmentActivity; |
| import androidx.viewpager.widget.ViewPager; |
| |
| import com.android.car.media.common.source.MediaSource; |
| import com.android.car.media.common.source.MediaSourceViewModel; |
| import com.android.car.radio.bands.ProgramType; |
| import com.android.car.radio.util.Log; |
| import com.android.car.ui.toolbar.MenuItem; |
| import com.android.car.ui.toolbar.TabLayout; |
| import com.android.car.ui.toolbar.Toolbar; |
| |
| import java.util.Arrays; |
| import java.util.List; |
| |
| /** |
| * The main activity for the radio app. |
| */ |
| public class RadioActivity extends FragmentActivity { |
| private static final String TAG = "BcRadioApp.activity"; |
| |
| /** |
| * Intent action for notifying that the radio state has changed. |
| */ |
| private static final String ACTION_RADIO_APP_STATE_CHANGE = |
| "android.intent.action.RADIO_APP_STATE_CHANGE"; |
| |
| /** |
| * Boolean Intent extra indicating if the radio is the currently in the foreground. |
| */ |
| private static final String EXTRA_RADIO_APP_FOREGROUND = |
| "android.intent.action.RADIO_APP_STATE"; |
| |
| private RadioController mRadioController; |
| private BandController mBandController = new BandController(); |
| private Toolbar mToolbar; |
| private RadioPagerAdapter mRadioPagerAdapter; |
| |
| @Override |
| protected void onCreate(Bundle savedInstanceState) { |
| super.onCreate(savedInstanceState); |
| |
| Log.d(TAG, "Radio app main activity created"); |
| |
| setContentView(R.layout.radio_activity); |
| |
| mRadioController = new RadioController(this); |
| mRadioController.getCurrentProgram().observe(this, info -> { |
| ProgramType programType = ProgramType.fromSelector(info.getSelector()); |
| if (programType != null) { |
| mBandController.setType(programType); |
| updateMenuItems(); |
| } |
| }); |
| |
| mRadioPagerAdapter = |
| new RadioPagerAdapter(this, getSupportFragmentManager(), mRadioController); |
| ViewPager viewPager = findViewById(R.id.viewpager); |
| viewPager.setAdapter(mRadioPagerAdapter); |
| |
| mToolbar = requireViewById(R.id.toolbar); |
| mToolbar.registerOnTabSelectedListener(t -> |
| viewPager.setCurrentItem(mToolbar.getTabLayout().getTabPosition(t))); |
| |
| updateMenuItems(); |
| setupTabsWithViewPager(viewPager); |
| |
| MediaSourceViewModel model = MediaSourceViewModel.get(getApplication()); |
| model.getPrimaryMediaSource().observe(this, source -> { |
| if (source != null) { |
| // Always go through the trampoline activity to keep all the dispatching logic |
| // there. |
| startActivity(new Intent(Car.CAR_INTENT_ACTION_MEDIA_TEMPLATE)); |
| } |
| }); |
| } |
| |
| @Override |
| protected void onStart() { |
| super.onStart(); |
| |
| mRadioController.start(); |
| |
| Intent broadcast = new Intent(ACTION_RADIO_APP_STATE_CHANGE); |
| broadcast.putExtra(EXTRA_RADIO_APP_FOREGROUND, true); |
| sendBroadcast(broadcast); |
| } |
| |
| @Override |
| protected void onStop() { |
| super.onStop(); |
| |
| Intent broadcast = new Intent(ACTION_RADIO_APP_STATE_CHANGE); |
| broadcast.putExtra(EXTRA_RADIO_APP_FOREGROUND, false); |
| sendBroadcast(broadcast); |
| } |
| |
| @Override |
| protected void onDestroy() { |
| super.onDestroy(); |
| |
| mRadioController.shutdown(); |
| |
| Log.d(TAG, "Radio app main activity destroyed"); |
| } |
| |
| @Override |
| public boolean onKeyDown(int keyCode, KeyEvent event) { |
| switch (keyCode) { |
| case KeyEvent.KEYCODE_MEDIA_STEP_FORWARD: |
| mRadioController.step(true); |
| return true; |
| case KeyEvent.KEYCODE_MEDIA_STEP_BACKWARD: |
| mRadioController.step(false); |
| return true; |
| default: |
| return super.onKeyDown(keyCode, event); |
| } |
| } |
| |
| /** |
| * Set whether background scanning is supported, to know whether to show the browse tab or not. |
| */ |
| public void setProgramListSupported(boolean supported) { |
| if (supported && mRadioPagerAdapter.addBrowseTab()) { |
| updateTabs(); |
| } |
| } |
| |
| /** |
| * Sets supported program types. |
| */ |
| public void setSupportedProgramTypes(@NonNull List<ProgramType> supported) { |
| mBandController.setSupportedProgramTypes(supported); |
| } |
| |
| private void setupTabsWithViewPager(ViewPager viewPager) { |
| viewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { |
| @Override |
| public void onPageSelected(int position) { |
| mToolbar.selectTab(position); |
| } |
| }); |
| updateTabs(); |
| } |
| |
| private void updateMenuItems() { |
| ProgramType currentBand = mBandController.getCurrentBand(); |
| MenuItem bandSelectorMenuItem = MenuItem.builder(this) |
| .setIcon(currentBand != null ? currentBand.getResourceId() : 0) |
| .setOnClickListener(i -> { |
| ProgramType programType = mBandController.switchToNext(); |
| mRadioController.switchBand(programType); |
| }) |
| .build(); |
| |
| Intent appSelectorIntent = MediaSource.getSourceSelectorIntent(this, false); |
| MenuItem appSelectorMenuItem = MenuItem.builder(this) |
| .setIcon(R.drawable.ic_app_switch) |
| .setOnClickListener(m -> startActivity(appSelectorIntent)) |
| .build(); |
| |
| mToolbar.setMenuItems(Arrays.asList(bandSelectorMenuItem, appSelectorMenuItem)); |
| } |
| |
| private void updateTabs() { |
| mToolbar.clearAllTabs(); |
| for (int i = 0; i < mRadioPagerAdapter.getCount(); i++) { |
| Drawable icon = mRadioPagerAdapter.getPageIcon(i); |
| CharSequence title = mRadioPagerAdapter.getPageTitle(i); |
| mToolbar.addTab(new TabLayout.Tab(icon, title)); |
| } |
| } |
| } |