1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 5 * except in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the 10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 11 * KIND, either express or implied. See the License for the specific language governing 12 * permissions and limitations under the License. 13 */ 14 package com.android.systemui; 15 16 import android.annotation.Nullable; 17 import android.content.Context; 18 import android.content.res.TypedArray; 19 import android.util.AttributeSet; 20 import android.util.Log; 21 import android.view.View; 22 23 import com.android.systemui.plugins.PluginListener; 24 import com.android.systemui.plugins.PluginManager; 25 import com.android.systemui.plugins.ViewProvider; 26 27 /** 28 * Define an interface or abstract class as follows that includes the 29 * version and action. 30 * 31 * public interface MyInterface { 32 * public static final String ACTION = 33 * "com.android.systemui.action.PLUGIN_MYINTERFACE"; 34 * 35 * public static final int VERSION = 1; 36 * 37 * void myImportantInterface(); 38 * } 39 * 40 * Then put in a PluginInflateContainer to use and specify the interface 41 * or class that will be implemented as viewType. The layout specified 42 * will be used by default and whenever a plugin is not present. 43 * 44 * <com.android.systemui.PluginInflateContainer 45 * android:id="@+id/some_id" 46 * android:layout_width="match_parent" 47 * android:layout_height="match_parent" 48 * android:layout="@layout/my_default_component" 49 * systemui:viewType="com.android.systemui.plugins.MyInterface" /> 50 */ 51 public class PluginInflateContainer extends AutoReinflateContainer 52 implements PluginListener<ViewProvider> { 53 54 private static final String TAG = "PluginInflateContainer"; 55 56 private Class<?> mClass; 57 private View mPluginView; 58 PluginInflateContainer(Context context, @Nullable AttributeSet attrs)59 public PluginInflateContainer(Context context, @Nullable AttributeSet attrs) { 60 super(context, attrs); 61 TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PluginInflateContainer); 62 String viewType = a.getString(R.styleable.PluginInflateContainer_viewType); 63 try { 64 mClass = Class.forName(viewType); 65 } catch (Exception e) { 66 Log.d(TAG, "Problem getting class info " + viewType, e); 67 mClass = null; 68 } 69 } 70 71 @Override onAttachedToWindow()72 protected void onAttachedToWindow() { 73 super.onAttachedToWindow(); 74 if (mClass != null) { 75 Dependency.get(PluginManager.class).addPluginListener(this, mClass); 76 } 77 } 78 79 @Override onDetachedFromWindow()80 protected void onDetachedFromWindow() { 81 super.onDetachedFromWindow(); 82 if (mClass != null) { 83 Dependency.get(PluginManager.class).removePluginListener(this); 84 } 85 } 86 87 @Override inflateLayoutImpl()88 protected void inflateLayoutImpl() { 89 if (mPluginView != null) { 90 addView(mPluginView); 91 } else { 92 super.inflateLayoutImpl(); 93 } 94 } 95 96 @Override onPluginConnected(ViewProvider plugin, Context context)97 public void onPluginConnected(ViewProvider plugin, Context context) { 98 mPluginView = plugin.getView(); 99 inflateLayout(); 100 } 101 102 @Override onPluginDisconnected(ViewProvider plugin)103 public void onPluginDisconnected(ViewProvider plugin) { 104 mPluginView = null; 105 inflateLayout(); 106 } 107 } 108