/* * 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.car.cluster.sample; import static android.car.cluster.sample.SampleClusterServiceImpl.LOCAL_BINDING_ACTION; import android.car.cluster.sample.SampleClusterServiceImpl.Listener; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.util.Log; import android.util.SparseArray; import android.view.InputDevice; import android.view.KeyEvent; import android.view.View; import android.view.inputmethod.InputMethodManager; import android.widget.Button; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentPagerAdapter; import androidx.viewpager.widget.ViewPager; import java.lang.reflect.InvocationTargetException; import java.util.HashMap; public class MainClusterActivity extends FragmentActivity implements Listener { private static final String TAG = MainClusterActivity.class.getSimpleName(); private ViewPager mPager; private SampleClusterServiceImpl mService; private HashMap> mButtonToFacet = new HashMap<>(); private SparseArray> mOrderToFacet = new SparseArray<>(); private InputMethodManager mInputMethodManager; private final View.OnFocusChangeListener mFacetButtonFocusListener = new View.OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { if (hasFocus) { mPager.setCurrentItem(mButtonToFacet.get(v).order); } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mInputMethodManager = getSystemService(InputMethodManager.class); Intent intent = new Intent(this, SampleClusterServiceImpl.class); intent.setAction(LOCAL_BINDING_ACTION); bindService(intent, new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { Log.i(TAG, "onServiceConnected, name: " + name + ", service: " + service); mService = ((SampleClusterServiceImpl.LocalBinder) service) .getService(); mService.registerListener(MainClusterActivity.this); } @Override public void onServiceDisconnected(ComponentName name) { Log.i(TAG, "onServiceDisconnected, name: " + name); mService = null; } }, BIND_AUTO_CREATE); registerFacets( new Facet<>(findViewById(R.id.btn_nav), 0, NavigationFragment.class), new Facet<>(findViewById(R.id.btn_phone), 1, PhoneFragment.class), new Facet<>(findViewById(R.id.btn_music), 2, MusicFragment.class), new Facet<>(findViewById(R.id.btn_car_info), 3, CarInfoFragment.class)); mPager = findViewById(R.id.pager); mPager.setAdapter(new ClusterPageAdapter(getSupportFragmentManager())); mOrderToFacet.get(0).button.requestFocus(); } @Override protected void onDestroy() { super.onDestroy(); if (mService != null) { mService.unregisterListener(); } } @Override public void onKeyEvent(KeyEvent event) { Log.i(TAG, "onKeyEvent, event: " + event); // This is a hack. We use SOURCE_CLASS_POINTER here because this type of input is associated // with the display. otherwise this event will be ignored in ViewRootImpl because injecting // KeyEvent w/o activity being focused is useless. event.setSource(event.getSource() | InputDevice.SOURCE_CLASS_POINTER); mInputMethodManager.dispatchKeyEventFromInputMethod(getCurrentFocus(), event); } public class ClusterPageAdapter extends FragmentPagerAdapter { public ClusterPageAdapter(FragmentManager fm) { super(fm); } @Override public int getCount() { return mButtonToFacet.size(); } @Override public Fragment getItem(int position) { return mOrderToFacet.get(position).getOrCreateFragment(); } } private void registerFacets(Facet... facets) { for (Facet f : facets) { registerFacet(f); } } private void registerFacet(Facet facet) { mOrderToFacet.append(facet.order, facet); mButtonToFacet.put(facet.button, facet); facet.button.setOnFocusChangeListener(mFacetButtonFocusListener); } private static class Facet { Button button; Class clazz; int order; Facet(Button button, int order, Class clazz) { this.button = button; this.order = order; this.clazz = clazz; } private Fragment mFragment; Fragment getOrCreateFragment() { if (mFragment == null) { try { mFragment = (Fragment) clazz.getConstructors()[0].newInstance(); } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { throw new RuntimeException(e); } } return mFragment; } } SampleClusterServiceImpl getService() { return mService; } }