1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.settings.core.codeinspection; 18 19 import static org.junit.Assert.fail; 20 21 import android.util.ArraySet; 22 23 import com.android.settingslib.core.lifecycle.LifecycleObserver; 24 import com.android.settingslib.core.lifecycle.events.OnAttach; 25 import com.android.settingslib.core.lifecycle.events.OnCreate; 26 import com.android.settingslib.core.lifecycle.events.OnCreateOptionsMenu; 27 import com.android.settingslib.core.lifecycle.events.OnDestroy; 28 import com.android.settingslib.core.lifecycle.events.OnOptionsItemSelected; 29 import com.android.settingslib.core.lifecycle.events.OnPause; 30 import com.android.settingslib.core.lifecycle.events.OnPrepareOptionsMenu; 31 import com.android.settingslib.core.lifecycle.events.OnResume; 32 import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState; 33 import com.android.settingslib.core.lifecycle.events.OnStart; 34 import com.android.settingslib.core.lifecycle.events.OnStop; 35 import com.android.settingslib.core.lifecycle.events.SetPreferenceScreen; 36 37 import java.util.Arrays; 38 import java.util.List; 39 import java.util.Set; 40 41 public class LifecycleObserverCodeInspector extends CodeInspector { 42 43 private static final List<Class> LIFECYCLE_EVENTS = Arrays.asList( 44 OnAttach.class, 45 OnCreate.class, 46 OnCreateOptionsMenu.class, 47 OnDestroy.class, 48 OnOptionsItemSelected.class, 49 OnPause.class, 50 OnPrepareOptionsMenu.class, 51 OnResume.class, 52 OnSaveInstanceState.class, 53 OnStart.class, 54 OnStop.class, 55 SetPreferenceScreen.class 56 ); 57 LifecycleObserverCodeInspector(List<Class<?>> classes)58 public LifecycleObserverCodeInspector(List<Class<?>> classes) { 59 super(classes); 60 } 61 62 @Override run()63 public void run() { 64 final Set<String> notImplementingLifecycleObserver = new ArraySet<>(); 65 for (Class clazz : mClasses) { 66 if (!isConcreteSettingsClass(clazz)) { 67 continue; 68 } 69 boolean classObservesLifecycleEvent = false; 70 for (Class event : LIFECYCLE_EVENTS) { 71 if (event.isAssignableFrom(clazz)) { 72 classObservesLifecycleEvent = true; 73 break; 74 } 75 } 76 if (classObservesLifecycleEvent && !LifecycleObserver.class.isAssignableFrom(clazz)) { 77 // Observes LifecycleEvent but not implementing LifecycleObserver. Something is 78 // wrong. 79 notImplementingLifecycleObserver.add(clazz.getName()); 80 } 81 } 82 if (!notImplementingLifecycleObserver.isEmpty()) { 83 final String errorTemplate = 84 "The following class(es) implements lifecycle.events.*, but don't " 85 + "implement LifecycleObserver. Something is wrong:\n"; 86 final StringBuilder error = new StringBuilder(errorTemplate); 87 for (String name : notImplementingLifecycleObserver) { 88 error.append(name).append('\n'); 89 } 90 fail(error.toString()); 91 } 92 } 93 } 94