1 /* 2 * Copyright (C) 2017 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 android.appwidget.cts; 18 19 import android.appwidget.AppWidgetProviderInfo; 20 import android.appwidget.AppWidgetManager; 21 import android.appwidget.AppWidgetHost; 22 import android.appwidget.cts.provider.FirstAppWidgetProvider; 23 import android.appwidget.cts.provider.SecondAppWidgetProvider; 24 import android.os.Bundle; 25 import android.test.suitebuilder.annotation.MediumTest; 26 import android.util.Log; 27 import android.content.ComponentName; 28 import android.content.Context; 29 import android.os.ParcelFileDescriptor; 30 import android.os.Process; 31 import android.test.InstrumentationTestCase; 32 import java.io.BufferedReader; 33 import java.io.InputStreamReader; 34 import java.util.ArrayList; 35 import java.util.List; 36 37 @MediumTest 38 public class AppWidgetTest extends InstrumentationTestCase { 39 40 private static final String TAG = "AppWidgetTest"; 41 private static final int HOST_ID = 1001; 42 private static final String GRANT_BIND_APP_WIDGET_PERMISSION_COMMAND = 43 "appwidget grantbind --package android.appwidget.cts --user 0"; 44 45 private Context mContext; 46 47 @Override setUp()48 public void setUp() throws Exception { 49 mContext = getInstrumentation().getTargetContext(); 50 // Workaround for dexmaker bug: https://code.google.com/p/dexmaker/issues/detail?id=2 51 // Dexmaker is used by mockito. 52 System.setProperty("dexmaker.dexcache", mContext.getCacheDir().getPath()); 53 } 54 testBindWidget1()55 public void testBindWidget1() throws Exception { 56 Log.d(TAG, "binding widget 1 ..."); 57 setupWidget(getFirstAppWidgetProviderInfo(), null, true); 58 Log.d(TAG, "binding widget 1 done"); 59 } 60 testBindWidget2()61 public void testBindWidget2() throws Exception { 62 Log.d(TAG, "binding widget 2 ..."); 63 Bundle options = new Bundle(); 64 options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH, 1); 65 options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT, 2); 66 options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH, 3); 67 options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT, 4); 68 setupWidget(getSecondAppWidgetProviderInfo(), options, true); 69 Log.d(TAG, "binding widget 2 done"); 70 } 71 testAllocateOnlyWidget1()72 public void testAllocateOnlyWidget1() throws Exception { 73 Log.d(TAG, "allocating widget 1 ..."); 74 setupWidget(getFirstAppWidgetProviderInfo(), null, false); 75 Log.d(TAG, "allocating widget 1 done"); 76 } 77 testCleanup()78 public void testCleanup() throws Exception { 79 Log.d(TAG, "deleting host"); 80 grantBindAppWidgetPermission(); 81 AppWidgetHost host = new AppWidgetHost(mContext, HOST_ID); 82 host.deleteHost(); 83 } 84 setupWidget(AppWidgetProviderInfo prov, Bundle options, boolean bindWidget)85 private void setupWidget(AppWidgetProviderInfo prov, Bundle options, boolean bindWidget) throws Exception { 86 // We want to bind widgets. 87 grantBindAppWidgetPermission(); 88 89 // Create a host and start listening. 90 AppWidgetHost host = new AppWidgetHost(mContext, HOST_ID); 91 host.deleteHost(); 92 host.startListening(); 93 94 AppWidgetManager mgr = getAppWidgetManager(); 95 96 // Initially we have no widgets. 97 assertEquals(0, mgr.getAppWidgetIds(prov.provider).length); 98 99 // Allocate the first widget id to bind. 100 int appWidgetId = host.allocateAppWidgetId(); 101 102 if (bindWidget) { 103 // Bind the widget. 104 getAppWidgetManager().bindAppWidgetIdIfAllowed(appWidgetId, 105 prov.getProfile(), prov.provider, options); 106 107 assertEquals(1, mgr.getAppWidgetIds(prov.provider).length); 108 } 109 } 110 getFirstWidgetComponent()111 private ComponentName getFirstWidgetComponent() { 112 return new ComponentName(mContext.getPackageName(), 113 FirstAppWidgetProvider.class.getName()); 114 } 115 getSecondWidgetComponent()116 private ComponentName getSecondWidgetComponent() { 117 return new ComponentName(mContext.getPackageName(), 118 SecondAppWidgetProvider.class.getName()); 119 } 120 runShellCommand(String command)121 private ArrayList<String> runShellCommand(String command) throws Exception { 122 ParcelFileDescriptor pfd = getInstrumentation().getUiAutomation() 123 .executeShellCommand(command); 124 125 ArrayList<String> ret = new ArrayList<>(); 126 // Read the input stream fully. 127 try (BufferedReader r = new BufferedReader( 128 new InputStreamReader(new ParcelFileDescriptor.AutoCloseInputStream(pfd)))) { 129 String line; 130 while ((line = r.readLine()) != null) { 131 ret.add(line); 132 } 133 } 134 return ret; 135 } 136 getFirstAppWidgetProviderInfo()137 private AppWidgetProviderInfo getFirstAppWidgetProviderInfo() { 138 return getProviderInfo(getFirstWidgetComponent()); 139 } 140 getSecondAppWidgetProviderInfo()141 private AppWidgetProviderInfo getSecondAppWidgetProviderInfo() { 142 return getProviderInfo(getSecondWidgetComponent()); 143 } 144 getProviderInfo(ComponentName componentName)145 private AppWidgetProviderInfo getProviderInfo(ComponentName componentName) { 146 List<AppWidgetProviderInfo> providers = getAppWidgetManager().getInstalledProviders(); 147 148 final int providerCount = providers.size(); 149 for (int i = 0; i < providerCount; i++) { 150 AppWidgetProviderInfo provider = providers.get(i); 151 if (componentName.equals(provider.provider) 152 && Process.myUserHandle().equals(provider.getProfile())) { 153 return provider; 154 155 } 156 } 157 158 return null; 159 } 160 getAppWidgetManager()161 private AppWidgetManager getAppWidgetManager() { 162 return (AppWidgetManager) getInstrumentation().getTargetContext() 163 .getSystemService(Context.APPWIDGET_SERVICE); 164 } 165 grantBindAppWidgetPermission()166 private void grantBindAppWidgetPermission() throws Exception { 167 runShellCommand(GRANT_BIND_APP_WIDGET_PERMISSION_COMMAND); 168 } 169 170 } 171