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