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 import com.android.systemui.res.R; 27 28 /** 29 * Define an interface or abstract class as follows that includes the 30 * version and action. 31 * 32 * public interface MyInterface { 33 * public static final String ACTION = 34 * "com.android.systemui.action.PLUGIN_MYINTERFACE"; 35 * 36 * public static final int VERSION = 1; 37 * 38 * void myImportantInterface(); 39 * } 40 * 41 * Then put in a PluginInflateContainer to use and specify the interface 42 * or class that will be implemented as viewType. The layout specified 43 * will be used by default and whenever a plugin is not present. 44 * 45 * <com.android.systemui.PluginInflateContainer 46 * android:id="@+id/some_id" 47 * android:layout_width="match_parent" 48 * android:layout_height="match_parent" 49 * android:layout="@layout/my_default_component" 50 * systemui:viewType="com.android.systemui.plugins.MyInterface" /> 51 */ 52 public class PluginInflateContainer extends AutoReinflateContainer 53 implements PluginListener<ViewProvider> { 54 55 private static final String TAG = "PluginInflateContainer"; 56 57 private Class<ViewProvider> mClass; 58 private View mPluginView; 59 PluginInflateContainer(Context context, @Nullable AttributeSet attrs)60 public PluginInflateContainer(Context context, @Nullable AttributeSet attrs) { 61 super(context, attrs); 62 TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PluginInflateContainer); 63 String viewType = a.getString(R.styleable.PluginInflateContainer_viewType); 64 a.recycle(); 65 try { 66 mClass = (Class<ViewProvider>) Class.forName(viewType); 67 } catch (Exception e) { 68 Log.d(TAG, "Problem getting class info " + viewType, e); 69 mClass = null; 70 } 71 } 72 73 @Override onAttachedToWindow()74 protected void onAttachedToWindow() { 75 super.onAttachedToWindow(); 76 if (mClass != null) { 77 Dependency.get(PluginManager.class).addPluginListener(this, mClass); 78 } 79 } 80 81 @Override onDetachedFromWindow()82 protected void onDetachedFromWindow() { 83 super.onDetachedFromWindow(); 84 if (mClass != null) { 85 Dependency.get(PluginManager.class).removePluginListener(this); 86 } 87 } 88 89 @Override inflateLayoutImpl()90 protected void inflateLayoutImpl() { 91 if (mPluginView != null) { 92 addView(mPluginView); 93 } else { 94 super.inflateLayoutImpl(); 95 } 96 } 97 98 @Override onPluginConnected(ViewProvider plugin, Context context)99 public void onPluginConnected(ViewProvider plugin, Context context) { 100 mPluginView = plugin.getView(); 101 inflateLayout(); 102 } 103 104 @Override onPluginDisconnected(ViewProvider plugin)105 public void onPluginDisconnected(ViewProvider plugin) { 106 mPluginView = null; 107 inflateLayout(); 108 } 109 } 110