1 /* 2 * Copyright (C) 2009 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.wallpaper.livepicker; 18 19 import android.app.Activity; 20 import android.app.WallpaperManager; 21 import android.app.WallpaperInfo; 22 import android.app.Dialog; 23 import android.service.wallpaper.IWallpaperConnection; 24 import android.service.wallpaper.IWallpaperService; 25 import android.service.wallpaper.IWallpaperEngine; 26 import android.service.wallpaper.WallpaperSettingsActivity; 27 import android.content.ServiceConnection; 28 import android.content.Intent; 29 import android.content.Context; 30 import android.content.ComponentName; 31 import android.os.RemoteException; 32 import android.os.IBinder; 33 import android.os.ParcelFileDescriptor; 34 import android.os.Bundle; 35 import android.view.MotionEvent; 36 import android.view.View; 37 import android.view.WindowManager; 38 import android.view.ViewGroup; 39 import android.view.Window; 40 import android.view.LayoutInflater; 41 import android.util.Log; 42 import android.widget.TextView; 43 44 public class LiveWallpaperPreview extends Activity { 45 static final String EXTRA_LIVE_WALLPAPER_INTENT = "android.live_wallpaper.intent"; 46 static final String EXTRA_LIVE_WALLPAPER_SETTINGS = "android.live_wallpaper.settings"; 47 static final String EXTRA_LIVE_WALLPAPER_PACKAGE = "android.live_wallpaper.package"; 48 49 private static final String LOG_TAG = "LiveWallpaperPreview"; 50 51 private WallpaperManager mWallpaperManager; 52 private WallpaperConnection mWallpaperConnection; 53 54 private String mSettings; 55 private String mPackageName; 56 private Intent mWallpaperIntent; 57 private View mView; 58 private Dialog mDialog; 59 60 static void showPreview(Activity activity, int code, Intent intent, WallpaperInfo info) { 61 if (info == null) { 62 Log.w(LOG_TAG, "Failure showing preview", new Throwable()); 63 return; 64 } 65 Intent preview = new Intent(activity, LiveWallpaperPreview.class); 66 preview.putExtra(EXTRA_LIVE_WALLPAPER_INTENT, intent); 67 preview.putExtra(EXTRA_LIVE_WALLPAPER_SETTINGS, info.getSettingsActivity()); 68 preview.putExtra(EXTRA_LIVE_WALLPAPER_PACKAGE, info.getPackageName()); 69 activity.startActivityForResult(preview, code); 70 } 71 72 @Override 73 protected void onCreate(Bundle savedInstanceState) { 74 super.onCreate(savedInstanceState); 75 76 Bundle extras = getIntent().getExtras(); 77 mWallpaperIntent = (Intent) extras.get(EXTRA_LIVE_WALLPAPER_INTENT); 78 if (mWallpaperIntent == null) { 79 setResult(RESULT_CANCELED); 80 finish(); 81 } 82 83 setContentView(R.layout.live_wallpaper_preview); 84 mView = findViewById(R.id.configure); 85 86 mSettings = extras.getString(EXTRA_LIVE_WALLPAPER_SETTINGS); 87 mPackageName = extras.getString(EXTRA_LIVE_WALLPAPER_PACKAGE); 88 if (mSettings == null) { 89 mView.setVisibility(View.GONE); 90 } 91 92 mWallpaperManager = WallpaperManager.getInstance(this); 93 94 mWallpaperConnection = new WallpaperConnection(mWallpaperIntent); 95 } 96 97 public void setLiveWallpaper(View v) { 98 try { 99 mWallpaperManager.getIWallpaperManager().setWallpaperComponent( 100 mWallpaperIntent.getComponent()); 101 mWallpaperManager.setWallpaperOffsetSteps(0.5f, 0.0f); 102 mWallpaperManager.setWallpaperOffsets(v.getRootView().getWindowToken(), 0.5f, 0.0f); 103 setResult(RESULT_OK); 104 } catch (RemoteException e) { 105 // do nothing 106 } catch (RuntimeException e) { 107 Log.w(LOG_TAG, "Failure setting wallpaper", e); 108 } 109 finish(); 110 } 111 112 @SuppressWarnings({"UnusedDeclaration"}) 113 public void configureLiveWallpaper(View v) { 114 Intent intent = new Intent(); 115 intent.setComponent(new ComponentName(mPackageName, mSettings)); 116 intent.putExtra(WallpaperSettingsActivity.EXTRA_PREVIEW_MODE, true); 117 startActivity(intent); 118 } 119 120 @Override 121 public void onResume() { 122 super.onResume(); 123 if (mWallpaperConnection != null && mWallpaperConnection.mEngine != null) { 124 try { 125 mWallpaperConnection.mEngine.setVisibility(true); 126 } catch (RemoteException e) { 127 // Ignore 128 } 129 } 130 } 131 132 @Override 133 public void onPause() { 134 super.onPause(); 135 if (mWallpaperConnection != null && mWallpaperConnection.mEngine != null) { 136 try { 137 mWallpaperConnection.mEngine.setVisibility(false); 138 } catch (RemoteException e) { 139 // Ignore 140 } 141 } 142 } 143 144 @Override 145 public void onAttachedToWindow() { 146 super.onAttachedToWindow(); 147 148 showLoading(); 149 150 mView.post(new Runnable() { 151 public void run() { 152 if (!mWallpaperConnection.connect()) { 153 mWallpaperConnection = null; 154 } 155 } 156 }); 157 } 158 159 private void showLoading() { 160 LayoutInflater inflater = LayoutInflater.from(this); 161 TextView content = (TextView) inflater.inflate(R.layout.live_wallpaper_loading, null); 162 163 mDialog = new Dialog(this, android.R.style.Theme_Black); 164 165 Window window = mDialog.getWindow(); 166 WindowManager.LayoutParams lp = window.getAttributes(); 167 168 lp.width = WindowManager.LayoutParams.MATCH_PARENT; 169 lp.height = WindowManager.LayoutParams.MATCH_PARENT; 170 window.setType(WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA); 171 172 mDialog.setContentView(content, new ViewGroup.LayoutParams( 173 ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT 174 )); 175 mDialog.show(); 176 } 177 178 @Override 179 public void onDetachedFromWindow() { 180 super.onDetachedFromWindow(); 181 182 if (mDialog != null) mDialog.dismiss(); 183 184 if (mWallpaperConnection != null) { 185 mWallpaperConnection.disconnect(); 186 } 187 mWallpaperConnection = null; 188 } 189 190 @Override 191 public boolean dispatchTouchEvent(MotionEvent ev) { 192 if (mWallpaperConnection != null && mWallpaperConnection.mEngine != null) { 193 MotionEvent dup = MotionEvent.obtainNoHistory(ev); 194 try { 195 mWallpaperConnection.mEngine.dispatchPointer(dup); 196 } catch (RemoteException e) { 197 } 198 } 199 200 if (ev.getAction() == MotionEvent.ACTION_DOWN) { 201 onUserInteraction(); 202 } 203 boolean handled = getWindow().superDispatchTouchEvent(ev); 204 if (!handled) { 205 handled = onTouchEvent(ev); 206 } 207 208 if (!handled && mWallpaperConnection != null && mWallpaperConnection.mEngine != null) { 209 int action = ev.getActionMasked(); 210 try { 211 if (action == MotionEvent.ACTION_UP) { 212 mWallpaperConnection.mEngine.dispatchWallpaperCommand( 213 WallpaperManager.COMMAND_TAP, 214 (int) ev.getX(), (int) ev.getY(), 0, null); 215 } else if (action == MotionEvent.ACTION_POINTER_UP) { 216 int pointerIndex = ev.getActionIndex(); 217 mWallpaperConnection.mEngine.dispatchWallpaperCommand( 218 WallpaperManager.COMMAND_SECONDARY_TAP, 219 (int) ev.getX(pointerIndex), (int) ev.getY(pointerIndex), 0, null); 220 } 221 } catch (RemoteException e) { 222 } 223 } 224 return handled; 225 } 226 227 class WallpaperConnection extends IWallpaperConnection.Stub implements ServiceConnection { 228 final Intent mIntent; 229 IWallpaperService mService; 230 IWallpaperEngine mEngine; 231 boolean mConnected; 232 233 WallpaperConnection(Intent intent) { 234 mIntent = intent; 235 } 236 237 public boolean connect() { 238 synchronized (this) { 239 if (!bindService(mIntent, this, Context.BIND_AUTO_CREATE)) { 240 return false; 241 } 242 243 mConnected = true; 244 return true; 245 } 246 } 247 248 public void disconnect() { 249 synchronized (this) { 250 mConnected = false; 251 if (mEngine != null) { 252 try { 253 mEngine.destroy(); 254 } catch (RemoteException e) { 255 // Ignore 256 } 257 mEngine = null; 258 } 259 unbindService(this); 260 mService = null; 261 } 262 } 263 264 public void onServiceConnected(ComponentName name, IBinder service) { 265 if (mWallpaperConnection == this) { 266 mService = IWallpaperService.Stub.asInterface(service); 267 try { 268 final View view = mView; 269 final View root = view.getRootView(); 270 mService.attach(this, view.getWindowToken(), 271 WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY, 272 true, root.getWidth(), root.getHeight()); 273 } catch (RemoteException e) { 274 Log.w(LOG_TAG, "Failed attaching wallpaper; clearing", e); 275 } 276 } 277 } 278 279 public void onServiceDisconnected(ComponentName name) { 280 mService = null; 281 mEngine = null; 282 if (mWallpaperConnection == this) { 283 Log.w(LOG_TAG, "Wallpaper service gone: " + name); 284 } 285 } 286 287 public void attachEngine(IWallpaperEngine engine) { 288 synchronized (this) { 289 if (mConnected) { 290 mEngine = engine; 291 try { 292 engine.setVisibility(true); 293 } catch (RemoteException e) { 294 // Ignore 295 } 296 } else { 297 try { 298 engine.destroy(); 299 } catch (RemoteException e) { 300 // Ignore 301 } 302 } 303 } 304 } 305 306 public ParcelFileDescriptor setWallpaper(String name) { 307 return null; 308 } 309 310 @Override 311 public void engineShown(IWallpaperEngine engine) throws RemoteException { 312 } 313 } 314 } 315